mirror of
https://github.com/lux-amm/v4-periphery.git
synced 2026-10-30 20:54:39 +00:00
123 lines
4.9 KiB
Solidity
123 lines
4.9 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.20;
|
|
|
|
import "forge-std/Test.sol";
|
|
import {UnorderedNonce, IUnorderedNonce} from "../src/base/UnorderedNonce.sol";
|
|
import {MockUnorderedNonce} from "./mocks/MockUnorderedNonce.sol";
|
|
|
|
contract UnorderedNonceTest is Test {
|
|
MockUnorderedNonce unorderedNonce;
|
|
|
|
function setUp() public {
|
|
unorderedNonce = new MockUnorderedNonce();
|
|
}
|
|
|
|
function testLowNonces() public {
|
|
unorderedNonce.spendNonce(address(this), 5);
|
|
unorderedNonce.spendNonce(address(this), 0);
|
|
unorderedNonce.spendNonce(address(this), 1);
|
|
|
|
vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector);
|
|
unorderedNonce.spendNonce(address(this), 1);
|
|
vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector);
|
|
unorderedNonce.spendNonce(address(this), 5);
|
|
vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector);
|
|
unorderedNonce.spendNonce(address(this), 0);
|
|
unorderedNonce.spendNonce(address(this), 4);
|
|
}
|
|
|
|
function testNonceWordBoundary() public {
|
|
unorderedNonce.spendNonce(address(this), 255);
|
|
unorderedNonce.spendNonce(address(this), 256);
|
|
|
|
vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector);
|
|
unorderedNonce.spendNonce(address(this), 255);
|
|
vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector);
|
|
unorderedNonce.spendNonce(address(this), 256);
|
|
}
|
|
|
|
function testHighNonces() public {
|
|
unorderedNonce.spendNonce(address(this), 2 ** 240);
|
|
unorderedNonce.spendNonce(address(this), 2 ** 240 + 1);
|
|
|
|
vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector);
|
|
unorderedNonce.spendNonce(address(this), 2 ** 240);
|
|
vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector);
|
|
unorderedNonce.spendNonce(address(this), 2 ** 240 + 1);
|
|
|
|
unorderedNonce.spendNonce(address(this), 2 ** 240 + 2);
|
|
}
|
|
|
|
function testInvalidateFullWord() public {
|
|
unorderedNonce.batchSpendNonces(0, 2 ** 256 - 1);
|
|
|
|
vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector);
|
|
unorderedNonce.spendNonce(address(this), 0);
|
|
vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector);
|
|
unorderedNonce.spendNonce(address(this), 1);
|
|
vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector);
|
|
unorderedNonce.spendNonce(address(this), 254);
|
|
vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector);
|
|
unorderedNonce.spendNonce(address(this), 255);
|
|
unorderedNonce.spendNonce(address(this), 256);
|
|
}
|
|
|
|
function testInvalidateNonzeroWord() public {
|
|
unorderedNonce.batchSpendNonces(1, 2 ** 256 - 1);
|
|
|
|
unorderedNonce.spendNonce(address(this), 0);
|
|
unorderedNonce.spendNonce(address(this), 254);
|
|
unorderedNonce.spendNonce(address(this), 255);
|
|
vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector);
|
|
unorderedNonce.spendNonce(address(this), 256);
|
|
vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector);
|
|
unorderedNonce.spendNonce(address(this), 511);
|
|
unorderedNonce.spendNonce(address(this), 512);
|
|
}
|
|
|
|
function test_fuzz_InvalidateNonzeroWord(uint256 word, uint256 nonce) public {
|
|
word = bound(word, 0, 1000e18);
|
|
// spend the entirety of a word
|
|
// word = 0, bits [0, 256)
|
|
// word = 1, bits [256, 512)
|
|
// word = 2, bits [512, 768), etc
|
|
unorderedNonce.batchSpendNonces(word, 2 ** 256 - 1);
|
|
|
|
// bound the nonce to be from 0 to 256 bits after the word
|
|
nonce = bound(nonce, 0, (word + 2) * 256);
|
|
|
|
if ((word * 256) <= nonce && nonce < ((word + 1) * 256)) {
|
|
vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector);
|
|
}
|
|
unorderedNonce.spendNonce(address(this), nonce);
|
|
}
|
|
|
|
function test_fuzz_UsingNonceTwiceFails(uint256 nonce) public {
|
|
unorderedNonce.spendNonce(address(this), nonce);
|
|
vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector);
|
|
unorderedNonce.spendNonce(address(this), nonce);
|
|
}
|
|
|
|
function test_fuzz_UseTwoRandomNonces(uint256 first, uint256 second) public {
|
|
unorderedNonce.spendNonce(address(this), first);
|
|
if (first == second) {
|
|
vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector);
|
|
unorderedNonce.spendNonce(address(this), second);
|
|
} else {
|
|
unorderedNonce.spendNonce(address(this), second);
|
|
}
|
|
}
|
|
|
|
function test_fuzz_revokeNonce(uint256 nonce) public {
|
|
unorderedNonce.revokeNonce(nonce);
|
|
vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector);
|
|
unorderedNonce.revokeNonce(nonce);
|
|
}
|
|
|
|
function test_fuzz_revokeNonce_twoNonces(uint256 first, uint256 second) public {
|
|
unorderedNonce.revokeNonce(first);
|
|
if (first == second) vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector);
|
|
unorderedNonce.revokeNonce(second);
|
|
}
|
|
}
|