Skip to content

Commit

Permalink
add more fuzz test
Browse files Browse the repository at this point in the history
  • Loading branch information
thurendous committed Sep 11, 2024
1 parent bc22c2c commit 3e21aa7
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 4 deletions.
106 changes: 105 additions & 1 deletion test/fuzz/FuzzVotingPowerExchange.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,99 @@ contract VotingPwoerExchangeTest is Test {
vm.label(user2, "user2");
}

///////////////////////////
//////////////////////////////
///// exchange functions /////
//////////////////////////////
function testExchangeWithAnySenderWhoIsNotTheSignerWillRevert(address anySender) public {
vm.assume(anySender != participant2);
vm.assume(anySender != address(0));
bytes32 nonce = bytes32(0);
uint256 expiration = block.timestamp + 1000000000;
(bytes memory signature,) = helper.generateSignatureFromPrivateKey(
dc.DEFAULT_ANVIL_KEY2(), 1_100 * 1e18, nonce, expiration, address(votingPowerExchange)
);

bytes32 digest = helper.createDigest(anySender, 1_100 * 1e18, nonce, expiration, address(votingPowerExchange));
vm.startPrank(exchanger);
vm.expectRevert(
abi.encodeWithSelector(
VotingPowerExchange.VotingPowerExchange__InvalidSignature.selector, digest, signature
)
);
votingPowerExchange.exchange(anySender, 1_100 * 1e18, nonce, expiration, signature);
vm.stopPrank();
}

function testExchangeWithAnyAmountLessThan1e18WillRevert(uint256 amount) public {
vm.assume(amount < 1e18);
bytes32 nonce = bytes32(0);
uint256 expiration = block.timestamp + 1000000000;
(bytes memory signature,) = helper.generateSignatureFromPrivateKey(
dc.DEFAULT_ANVIL_KEY2(), amount, nonce, expiration, address(votingPowerExchange)
);

vm.startPrank(exchanger);
vm.expectRevert(VotingPowerExchange.VotingPowerExchange__AmountIsTooSmall.selector);
votingPowerExchange.exchange(participant2, amount, nonce, expiration, signature);
vm.stopPrank();
}

function testExchangeWithAnyAmountWhichIsInRangeWillSucceed(uint256 amount) public {
// mint 75240 utility token to the participant2
vm.startPrank(minter);
utilityToken.mint(participant2, 75240 * 1e18);
vm.stopPrank();
// start testing
amount = bound(amount, 1e18, 75240 * 1e18);
bytes32 nonce = bytes32(0);
uint256 expiration = block.timestamp + 1000000000;
(bytes memory signature,) = helper.generateSignatureFromPrivateKey(
dc.DEFAULT_ANVIL_KEY2(), amount, nonce, expiration, address(votingPowerExchange)
);
vm.startPrank(exchanger);
votingPowerExchange.exchange(participant2, amount, nonce, expiration, signature);
vm.stopPrank();
// check the balance of the participant2
assertEq(utilityToken.balanceOf(participant2), 85240 * 1e18 - amount); // he got 10000 token in advance
uint256 exchangedVotingPower = votingPowerExchange.calculateIncrementedVotingPower(amount, 0);
// check the balance of the govToken
assertEq(govToken.balanceOf(participant2), exchangedVotingPower);
}

function testExchangeWithAnyRoleWhoIsNotExchangerWillRevert(address anyRole) public {
vm.assume(anyRole != exchanger);
bytes32 nonce = bytes32(0);
uint256 expiration = block.timestamp + 1000000000;
(bytes memory signature,) = helper.generateSignatureFromPrivateKey(
dc.DEFAULT_ANVIL_KEY2(), 1_100 * 1e18, nonce, expiration, address(votingPowerExchange)
);

vm.startPrank(anyRole);
vm.expectRevert(
abi.encodeWithSelector(
IAccessControl.AccessControlUnauthorizedAccount.selector, anyRole, votingPowerExchange.EXCHANGER_ROLE()
)
);
votingPowerExchange.exchange(participant2, 1_100 * 1e18, nonce, expiration, signature);
vm.stopPrank();
}

function testExchangeWithAnyNonceWhichIsUsedWillRevert(bytes32 badNonce) public {
uint256 expiration = block.timestamp + 1000000000;
(bytes memory signature,) = helper.generateSignatureFromPrivateKey(
dc.DEFAULT_ANVIL_KEY2(), 1_100 * 1e18, badNonce, expiration, address(votingPowerExchange)
);

vm.startPrank(exchanger);
votingPowerExchange.exchange(participant2, 1_100 * 1e18, badNonce, expiration, signature);
(bytes memory signature2,) = helper.generateSignatureFromPrivateKey(
dc.DEFAULT_ANVIL_KEY2(), 1_100 * 1e18, badNonce, expiration, address(votingPowerExchange)
);
vm.expectRevert(VotingPowerExchange.VotingPowerExchange__InvalidNonce.selector);
votingPowerExchange.exchange(participant2, 1_100 * 1e18, badNonce, expiration, signature2);
vm.stopPrank();
}

///// Other functions /////
///////////////////////////
/// The `setVotingPowerCap` function
Expand Down Expand Up @@ -109,6 +201,7 @@ contract VotingPwoerExchangeTest is Test {
votingPowerExchange.setVotingPowerCap(100e18);
}

// testing the calculation of voting power token <-> burned token
///////////////////////////////////////////////////////////
/// Test the `calculateIncrementedVotingPower` function ///
///////////////////////////////////////////////////////////
Expand Down Expand Up @@ -233,6 +326,17 @@ contract VotingPwoerExchangeTest is Test {
assertTrue(incrementedVotingPower <= 10e18);
}

function testCalculateIncrementedVotingPower_100_to_110(uint256 incrementedAmount) public view {
// limit the incrementedAmount to a reasonable range
incrementedAmount = bound(incrementedAmount, 0, 15925e18);
uint256 currentBurnedAmount = uint256(76750e18);

uint256 incrementedVotingPower =
votingPowerExchange.calculateIncrementedVotingPower(incrementedAmount, currentBurnedAmount);
assertTrue(incrementedVotingPower >= 0e18);
assertTrue(incrementedVotingPower <= 10e18);
}

function testCalculateIncrementedVotingPower_10_to_110(uint256 incrementedAmount) public view {
// limit the incrementedAmount to a reasonable range
incrementedAmount = bound(incrementedAmount, 925e18, 92675e18);
Expand Down
26 changes: 26 additions & 0 deletions test/integration/utils/VotingPowerExchangeTestHelper.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,30 @@ contract VotingPowerExchangeTestHelper is Test {

return (abi.encodePacked(r, s, v), hash);
}

/**
* @dev Creates a digest for EIP-712
* @param sender The address of the sender
* @param amount The amount of utility token to be exchanged
* @param nonce The nonce used in the exchange transaction
* @param expiration The expiration time of the signature
* @return The digest of the EIP-712
*/
function createDigest(address sender, uint256 amount, bytes32 nonce, uint256 expiration, address exchangeAddr)
public
view
returns (bytes32)
{
bytes32 structHash = keccak256(abi.encode(_EXCHANGE_TYPEHASH, sender, amount, nonce, expiration));
bytes32 domainSeparator = keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes("VotingPowerExchange")),
keccak256(bytes("1")),
block.chainid,
exchangeAddr
)
);
return MessageHashUtils.toTypedDataHash(domainSeparator, structHash);
}
}
10 changes: 7 additions & 3 deletions test/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,16 +139,20 @@ other functions

## voting power calculation table

These are the values we used in the fuzz tests for voint power <->
These are the values we used in the fuzz tests for voting power <-> burned token calculation.

- Function:

```
x = (2 \* sqrt(306.25 + 30y) - 5) / 30 - 1
y = (15*x^2+35*x)/2
x = mintedToken
y = burnedToken
x: mintedToken
y: burnedToken
```

- Table:

| Minted Token (lvl) | Level | Burned Token |
| ------------------ | ----- | ------------ |
| 0 | 1 | 0 |
Expand Down

0 comments on commit 3e21aa7

Please sign in to comment.