From 4e18607110f4efc7c752499160dfbb4827ba217a Mon Sep 17 00:00:00 2001 From: telome <> Date: Wed, 24 May 2023 17:24:45 +0100 Subject: [PATCH 1/7] forge install: token-tests dev --- .gitmodules | 3 +++ lib/token-tests | 1 + 2 files changed, 4 insertions(+) create mode 160000 lib/token-tests diff --git a/.gitmodules b/.gitmodules index 98ffb6a..9206859 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "lib/dss-test"] path = lib/dss-test url = https://github.com/makerdao/dss-test +[submodule "lib/token-tests"] + path = lib/token-tests + url = https://github.com/makerdao/token-tests diff --git a/lib/token-tests b/lib/token-tests new file mode 160000 index 0000000..a704472 --- /dev/null +++ b/lib/token-tests @@ -0,0 +1 @@ +Subproject commit a704472ba7e1d2e9049af2604be31fa02abe0f89 From d259bc0ce3c0bf41da8719965ffe608aae698277 Mon Sep 17 00:00:00 2001 From: telome <> Date: Wed, 24 May 2023 21:15:23 +0100 Subject: [PATCH 2/7] Use the token-tests lib --- lib/token-tests | 2 +- src/SDAO.t.sol | 442 +----------------------------------------------- 2 files changed, 8 insertions(+), 436 deletions(-) diff --git a/lib/token-tests b/lib/token-tests index a704472..12886bb 160000 --- a/lib/token-tests +++ b/lib/token-tests @@ -1 +1 @@ -Subproject commit a704472ba7e1d2e9049af2604be31fa02abe0f89 +Subproject commit 12886bb292b6d0e8f97dc9eaae2f03ff63453bf0 diff --git a/src/SDAO.t.sol b/src/SDAO.t.sol index 957bcbc..2361348 100644 --- a/src/SDAO.t.sol +++ b/src/SDAO.t.sol @@ -15,6 +15,7 @@ // along with this program. If not, see . pragma solidity =0.8.19; +import {TokenFuzzTests} from "token-tests/TokenFuzzTests.sol"; import {DssTest} from "dss-test/DssTest.sol"; import {GodMode} from "dss-test/MCD.sol"; import {SDAO} from "./SDAO.sol"; @@ -23,14 +24,16 @@ import {SDAO} from "./SDAO.sol"; * @dev Adapted from Solmate ERC20 test suite: * https://github.com/transmissions11/solmate/blob/2001af43aedb46fdc2335d2a7714fb2dae7cfcd1/src/test/ERC20.t.sol */ -contract SDAOTest is DssTest { +contract SDAOTest is TokenFuzzTests { SDAO token; - bytes32 constant PERMIT_TYPEHASH = - keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); - function setUp() public { token = new SDAO("Token", "TKN"); + + _token_ = address(token); + _tokenName_ ="Token"; + _contractName_ = "SDAO"; + _symbol_ = "TKN"; } function invariantMetadata() public { @@ -44,192 +47,6 @@ contract SDAOTest is DssTest { token.file("decimals", "18"); } - function testMint() public { - token.mint(address(0xBEEF), 1e18); - - assertEq(token.totalSupply(), 1e18); - assertEq(token.balanceOf(address(0xBEEF)), 1e18); - } - - function testBurn() public { - token.mint(address(0xBEEF), 1e18); - vm.prank(address(0xBEEF)); - token.approve(address(this), type(uint256).max); - - token.burn(address(0xBEEF), 0.9e18); - - assertEq(token.totalSupply(), 1e18 - 0.9e18); - assertEq(token.balanceOf(address(0xBEEF)), 0.1e18); - } - - function testApprove() public { - assertTrue(token.approve(address(0xBEEF), 1e18)); - - assertEq(token.allowance(address(this), address(0xBEEF)), 1e18); - } - - function testTransfer() public { - token.mint(address(this), 1e18); - - assertTrue(token.transfer(address(0xBEEF), 1e18)); - assertEq(token.totalSupply(), 1e18); - - assertEq(token.balanceOf(address(this)), 0); - assertEq(token.balanceOf(address(0xBEEF)), 1e18); - } - - function testTransferFrom() public { - address from = address(0xABCD); - token.mint(from, 1e18); - vm.prank(from); - token.approve(address(this), 1e18); - - assertTrue(token.transferFrom(from, address(0xBEEF), 1e18)); - - assertEq(token.totalSupply(), 1e18); - assertEq(token.allowance(from, address(this)), 0); - assertEq(token.balanceOf(from), 0); - assertEq(token.balanceOf(address(0xBEEF)), 1e18); - } - - function testInfiniteApproveTransferFrom() public { - address from = address(0xABCD); - token.mint(from, 1e18); - vm.prank(from); - token.approve(address(this), type(uint256).max); - - assertTrue(token.transferFrom(from, address(0xBEEF), 1e18)); - - assertEq(token.totalSupply(), 1e18); - assertEq(token.allowance(from, address(this)), type(uint256).max); - assertEq(token.balanceOf(from), 0); - assertEq(token.balanceOf(address(0xBEEF)), 1e18); - } - - function testPermit() public { - uint256 privateKey = 0xBEEF; - address owner = vm.addr(privateKey); - (uint8 v, bytes32 r, bytes32 s) = vm.sign( - privateKey, - keccak256( - abi.encodePacked( - "\x19\x01", - token.DOMAIN_SEPARATOR(), - keccak256( - abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, token.nonces(owner), block.timestamp) - ) - ) - ) - ); - - token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s); - - assertEq(token.allowance(owner, address(0xCAFE)), 1e18); - assertEq(token.nonces(owner), 1); - } - - function testRevertTransferInsufficientBalance() public { - token.mint(address(this), 0.9e18); - - vm.expectRevert("SDAO/insufficient-balance"); - token.transfer(address(0xBEEF), 1e18); - } - - function testRevertTransferFromInsufficientAllowance() public { - address from = address(0xABCD); - token.mint(from, 1e18); - vm.prank(from); - token.approve(address(this), 0.9e18); - - vm.expectRevert("SDAO/insufficient-allowance"); - token.transferFrom(from, address(0xBEEF), 1e18); - } - - function testRevertTransferFromInsufficientBalance() public { - address from = address(0xABCD); - token.mint(from, 0.9e18); - vm.prank(from); - token.approve(address(this), 1e18); - - vm.expectRevert("SDAO/insufficient-balance"); - token.transferFrom(from, address(0xBEEF), 1e18); - } - - function testRevertPermitBadNonce() public { - uint256 privateKey = 0xBEEF; - address owner = vm.addr(privateKey); - (uint8 v, bytes32 r, bytes32 s) = vm.sign( - privateKey, - keccak256( - abi.encodePacked( - "\x19\x01", - token.DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 1, block.timestamp)) - ) - ) - ); - - vm.expectRevert("SDAO/invalid-permit"); - token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s); - } - - function testRevertPermitBadDeadline() public { - uint256 privateKey = 0xBEEF; - address owner = vm.addr(privateKey); - (uint8 v, bytes32 r, bytes32 s) = vm.sign( - privateKey, - keccak256( - abi.encodePacked( - "\x19\x01", - token.DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 0, block.timestamp)) - ) - ) - ); - - vm.expectRevert("SDAO/invalid-permit"); - token.permit(owner, address(0xCAFE), 1e18, block.timestamp + 1, v, r, s); - } - - function testRevertPermitPastDeadline() public { - uint256 oldTimestamp = block.timestamp; - uint256 privateKey = 0xBEEF; - address owner = vm.addr(privateKey); - (uint8 v, bytes32 r, bytes32 s) = vm.sign( - privateKey, - keccak256( - abi.encodePacked( - "\x19\x01", - token.DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 0, oldTimestamp)) - ) - ) - ); - - vm.warp(block.timestamp + 1); - vm.expectRevert("SDAO/permit-expired"); - token.permit(owner, address(0xCAFE), 1e18, oldTimestamp, v, r, s); - } - - function testRevertPermitReplay() public { - uint256 privateKey = 0xBEEF; - address owner = vm.addr(privateKey); - (uint8 v, bytes32 r, bytes32 s) = vm.sign( - privateKey, - keccak256( - abi.encodePacked( - "\x19\x01", - token.DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 0, block.timestamp)) - ) - ) - ); - token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s); - - vm.expectRevert("SDAO/invalid-permit"); - token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s); - } - function testMetadataFuzz(string calldata name, string calldata symbol) public { SDAO tkn = new SDAO(name, symbol); assertEq(tkn.name(), name); @@ -237,251 +54,6 @@ contract SDAOTest is DssTest { assertEq(tkn.decimals(), 18); } - function testMintFuzz(address to, uint256 amount) public { - vm.assume(to != address(0) && to != address(token)); - - token.mint(to, amount); - - assertEq(token.totalSupply(), amount); - assertEq(token.balanceOf(to), amount); - } - - function testBurnFuzz(address from, uint256 mintAmount, uint256 burnAmount) public { - vm.assume(from != address(0) && from != address(token)); - burnAmount = bound(burnAmount, 0, mintAmount); - - token.mint(from, mintAmount); - vm.prank(from); - token.approve(address(this), type(uint256).max); - - token.burn(from, burnAmount); - - assertEq(token.totalSupply(), mintAmount - burnAmount); - assertEq(token.balanceOf(from), mintAmount - burnAmount); - } - - function testApproveFuzz(address to, uint256 amount) public { - vm.assume(to != address(0) && to != address(token)); - - assertTrue(token.approve(to, amount)); - - assertEq(token.allowance(address(this), to), amount); - } - - function testTransferFuzz(address to, uint256 amount) public { - vm.assume(to != address(0) && to != address(token)); - - token.mint(address(this), amount); - - assertTrue(token.transfer(to, amount)); - - assertEq(token.totalSupply(), amount); - if (address(this) == to) { - assertEq(token.balanceOf(address(this)), amount); - } else { - assertEq(token.balanceOf(address(this)), 0); - assertEq(token.balanceOf(to), amount); - } - } - - function testTransferFromFuzz(address to, uint256 allowance, uint256 amount) public { - vm.assume(to != address(0) && to != address(token)); - amount = bound(amount, 0, allowance); - - address from = address(0xABCD); - token.mint(from, amount); - vm.prank(from); - token.approve(address(this), allowance); - - assertTrue(token.transferFrom(from, to, amount)); - - assertEq(token.totalSupply(), amount); - - uint256 newAllowance = from == address(this) || allowance == type(uint256).max ? allowance : allowance - amount; - assertEq(token.allowance(from, address(this)), newAllowance); - - if (from == to) { - assertEq(token.balanceOf(from), amount); - } else { - assertEq(token.balanceOf(from), 0); - assertEq(token.balanceOf(to), amount); - } - } - - function testPermitFuzz(uint248 privateKey, address to, uint256 amount, uint256 deadline) public { - deadline = bound(deadline, block.timestamp, block.timestamp + type(uint80).max); - privateKey = uint248(bound(privateKey, 1, type(uint248).max)); - - address owner = vm.addr(privateKey); - (uint8 v, bytes32 r, bytes32 s) = vm.sign( - privateKey, - keccak256( - abi.encodePacked( - "\x19\x01", - token.DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, to, amount, 0, deadline)) - ) - ) - ); - - token.permit(owner, to, amount, deadline, v, r, s); - - assertEq(token.allowance(owner, to), amount); - assertEq(token.nonces(owner), 1); - } - - function testRevertBurnInsufficientBalanceFuzz(address to, uint256 mintAmount, uint256 burnAmount) public { - vm.assume(to != address(0) && to != address(token)); - mintAmount = bound(mintAmount, 0, type(uint256).max - 1); - burnAmount = bound(burnAmount, mintAmount + 1, type(uint256).max); - - token.mint(to, mintAmount); - - vm.expectRevert("SDAO/insufficient-balance"); - token.burn(to, burnAmount); - } - - function testRevertTransferInsufficientBalanceFuzz(address to, uint256 mintAmount, uint256 sendAmount) public { - vm.assume(to != address(0) && to != address(token)); - mintAmount = bound(mintAmount, 0, type(uint256).max - 1); - sendAmount = bound(sendAmount, mintAmount + 1, type(uint256).max); - - token.mint(address(this), mintAmount); - - vm.expectRevert("SDAO/insufficient-balance"); - token.transfer(to, sendAmount); - } - - function testRevertTransferFromInsufficientAllowanceFuzz(address to, uint256 allowance, uint256 amount) public { - vm.assume(to != address(0) && to != address(token)); - allowance = bound(allowance, 0, type(uint256).max - 1); - amount = bound(amount, allowance + 1, type(uint256).max); - - address from = address(0xABCD); - token.mint(from, amount); - vm.prank(from); - token.approve(address(this), allowance); - - vm.expectRevert("SDAO/insufficient-allowance"); - token.transferFrom(from, to, amount); - } - - function testRevertTransferFromInsufficientBalanceFuzz(address to, uint256 mintAmount, uint256 sendAmount) public { - vm.assume(to != address(0) && to != address(token)); - mintAmount = bound(mintAmount, 0, type(uint256).max - 1); - sendAmount = bound(sendAmount, mintAmount + 1, type(uint256).max); - - address from = address(0xABCD); - token.mint(from, mintAmount); - vm.prank(from); - token.approve(address(this), sendAmount); - - vm.expectRevert("SDAO/insufficient-balance"); - token.transferFrom(from, to, sendAmount); - } - - function testRevertPermitBadNonceFuzz( - uint248 privateKey, - address to, - uint256 amount, - uint256 deadline, - uint256 nonce - ) public { - deadline = bound(deadline, block.timestamp, block.timestamp + type(uint80).max); - privateKey = uint248(bound(privateKey, 1, type(uint248).max)); - nonce = bound(nonce, 1, type(uint256).max - 1); - - address owner = vm.addr(privateKey); - (uint8 v, bytes32 r, bytes32 s) = vm.sign( - privateKey, - keccak256( - abi.encodePacked( - "\x19\x01", - token.DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, to, amount, nonce, deadline)) - ) - ) - ); - - vm.expectRevert("SDAO/invalid-permit"); - token.permit(owner, to, amount, deadline, v, r, s); - } - - function testRevertPermitBadDeadlineFuzz(uint248 privateKey, address to, uint256 amount, uint256 deadline) public { - deadline = bound(deadline, block.timestamp, block.timestamp + type(uint80).max); - privateKey = uint248(bound(privateKey, 1, type(uint248).max)); - - address owner = vm.addr(privateKey); - (uint8 v, bytes32 r, bytes32 s) = vm.sign( - privateKey, - keccak256( - abi.encodePacked( - "\x19\x01", - token.DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, to, amount, 0, deadline)) - ) - ) - ); - - vm.expectRevert("SDAO/invalid-permit"); - token.permit(owner, to, amount, deadline + 1, v, r, s); - } - - function testRevertPermitPastDeadlineFuzz(uint248 privateKey, address to, uint256 amount, uint256 deadline) public { - deadline = bound(deadline, 0, block.timestamp - 1); - privateKey = uint248(bound(privateKey, 1, type(uint248).max)); - - address owner = vm.addr(privateKey); - (uint8 v, bytes32 r, bytes32 s) = vm.sign( - privateKey, - keccak256( - abi.encodePacked( - "\x19\x01", - token.DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, to, amount, 0, deadline)) - ) - ) - ); - - vm.expectRevert("SDAO/permit-expired"); - token.permit(owner, to, amount, deadline, v, r, s); - } - - function testRevertPermitReplayFuzz(uint248 privateKey, address to, uint256 amount, uint256 deadline) public { - deadline = bound(deadline, block.timestamp, block.timestamp + type(uint80).max); - privateKey = uint248(bound(privateKey, 1, type(uint248).max)); - - address owner = vm.addr(privateKey); - (uint8 v, bytes32 r, bytes32 s) = vm.sign( - privateKey, - keccak256( - abi.encodePacked( - "\x19\x01", - token.DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, to, amount, 0, deadline)) - ) - ) - ); - token.permit(owner, to, amount, deadline, v, r, s); - - vm.expectRevert("SDAO/invalid-permit"); - token.permit(owner, to, amount, deadline, v, r, s); - } - - function testAuth() public { - checkAuth(address(token), "SDAO"); - } - - function testModifiers(address sender) public { - vm.assume(sender != address(this)); - - bytes4[] memory authedMethods = new bytes4[](1); - authedMethods[0] = SDAO.mint.selector; - - vm.startPrank(sender); - checkModifier(address(token), "SDAO/not-authorized", authedMethods); - } - function testFile() public { checkFileString(address(token), "SDAO", ["name", "symbol"]); } From 0761ffa4b645550097777b8add5d5c8a67d4eacf Mon Sep 17 00:00:00 2001 From: telome <> Date: Thu, 25 May 2023 16:38:53 +0100 Subject: [PATCH 3/7] Update token-tests --- lib/token-tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/token-tests b/lib/token-tests index 12886bb..f0e734f 160000 --- a/lib/token-tests +++ b/lib/token-tests @@ -1 +1 @@ -Subproject commit 12886bb292b6d0e8f97dc9eaae2f03ff63453bf0 +Subproject commit f0e734f88d80d051bf7414523d4070c0e850c155 From 1da32f2d1e3dd65ebb1c43d1c09e3daf088b7910 Mon Sep 17 00:00:00 2001 From: telome <> Date: Thu, 25 May 2023 20:48:19 +0100 Subject: [PATCH 4/7] Update token-tests --- lib/token-tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/token-tests b/lib/token-tests index f0e734f..55a3eee 160000 --- a/lib/token-tests +++ b/lib/token-tests @@ -1 +1 @@ -Subproject commit f0e734f88d80d051bf7414523d4070c0e850c155 +Subproject commit 55a3eee4a4dcd2d0dc15f35a7aee63dbb0f4555a From b86d84a44c82a40011cd88bb0aa5950d6cccc503 Mon Sep 17 00:00:00 2001 From: telome <> Date: Fri, 26 May 2023 17:46:10 +0100 Subject: [PATCH 5/7] Update libs --- lib/token-tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/token-tests b/lib/token-tests index 55a3eee..708ca7b 160000 --- a/lib/token-tests +++ b/lib/token-tests @@ -1 +1 @@ -Subproject commit 55a3eee4a4dcd2d0dc15f35a7aee63dbb0f4555a +Subproject commit 708ca7bf1e9613b7da2718950b6d0b5e84c9f9d5 From 4acf9edad7f424feabbbb3573464de0c3d37a04a Mon Sep 17 00:00:00 2001 From: telome <> Date: Wed, 31 May 2023 11:40:17 +0100 Subject: [PATCH 6/7] Update token-tests --- lib/token-tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/token-tests b/lib/token-tests index 708ca7b..79d9e12 160000 --- a/lib/token-tests +++ b/lib/token-tests @@ -1 +1 @@ -Subproject commit 708ca7bf1e9613b7da2718950b6d0b5e84c9f9d5 +Subproject commit 79d9e125ef7580805c99a86a3f6c92c7503ebabc From 429a553386eb6546cf9009589be30ef602d29b2e Mon Sep 17 00:00:00 2001 From: amusingaxl <112016538+amusingaxl@users.noreply.github.com> Date: Thu, 8 Jun 2023 11:22:01 -0300 Subject: [PATCH 7/7] fix: bad setup after merge --- src/SDAO.t.sol | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/src/SDAO.t.sol b/src/SDAO.t.sol index 2016bf1..2bdf77d 100644 --- a/src/SDAO.t.sol +++ b/src/SDAO.t.sol @@ -25,46 +25,38 @@ import {SDAO} from "./SDAO.sol"; * https://github.com/transmissions11/solmate/blob/2001af43aedb46fdc2335d2a7714fb2dae7cfcd1/src/test/ERC20.t.sol */ contract SDAOTest is TokenFuzzTests { - SDAO token; - BalanceSum balanceSum; + SDAO internal token; + BalanceSum internal balanceSum; function setUp() public { token = new SDAO("Token", "TKN"); _token_ = address(token); - _tokenName_ ="Token"; + _tokenName_ = "Token"; _contractName_ = "SDAO"; _symbol_ = "TKN"; + + balanceSum = new BalanceSum(token); + token.rely(address(balanceSum)); + excludeSender(address(0)); + targetContract(address(balanceSum)); } function invariantBalanceSum() public { assertEq(token.totalSupply(), balanceSum.sum()); } - function testMetadata() public { - assertEq(token.name(), "Token"); - assertEq(token.symbol(), "TKN"); - assertEq(token.decimals(), 18); - } - function testRevertFileUnsupportedMetadata() public { vm.expectRevert("SDAO/file-unrecognized-param"); token.file("decimals", "18"); } - function testMetadataFuzz(string calldata name, string calldata symbol) public { - SDAO tkn = new SDAO(name, symbol); - assertEq(tkn.name(), name); - assertEq(tkn.symbol(), symbol); - assertEq(tkn.decimals(), 18); - } - function testFile() public { checkFileString(address(token), "SDAO", ["name", "symbol"]); } } contract BalanceSum is DssTest { - SDAO public token; + SDAO internal token; uint256 public sum; constructor(SDAO _token) {