Skip to content

Commit

Permalink
add some failing test
Browse files Browse the repository at this point in the history
  • Loading branch information
thurendous committed Sep 9, 2024
1 parent 5e5d53e commit 9e1fda0
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 12 deletions.
6 changes: 4 additions & 2 deletions src/VotingPowerExchange.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ contract VotingPowerExchange is AccessControl, EIP712 {
error VotingPowerExchange__AmountIsTooSmall();
error VotingPowerExchange__InvalidNonce();
error VotingPowerExchange__SignatureExpired();
error VotingPowerExchange__InvalidSignature();
error VotingPowerExchange__InvalidSignature(bytes32 digest, bytes signature);
error VotingPowerExchange__LevelIsLowerThanExisting();
error VotingPowerExchange__VotingPowerIsHigherThanCap(uint256 currentVotingPower);

Expand Down Expand Up @@ -111,7 +111,9 @@ contract VotingPowerExchange is AccessControl, EIP712 {

// create the digest for EIP-712 and validate the signature by the `sender`
bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(_EXCHANGE_TYPEHASH, sender, amount, nonce, expiration)));
if (!sender.isValidSignatureNow(digest, signature)) revert VotingPowerExchange__InvalidSignature();
if (!sender.isValidSignatureNow(digest, signature)) {
revert VotingPowerExchange__InvalidSignature(digest, signature);
}

// set the nonce as true after validating the signature
_authorizationStates[sender][nonce] = true;
Expand Down
59 changes: 56 additions & 3 deletions test/integration/VotingPowerExchange.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {ERC20UpgradeableTokenV1} from "src/ERC20UpgradeableTokenV1.sol";
import {GovToken} from "src/GovToken.sol";
import {VotingPowerExchange} from "src/VotingPowerExchange.sol";
import {VotingPowerExchangeTestHelper} from "./utils/VotingPowerExchangeTestHelper.t.sol";
import {MessageHashUtils} from "lib/openzeppelin-contracts/contracts/utils/cryptography/MessageHashUtils.sol";

contract VotingPwoerExchangeTest is Test {
// instances
Expand Down Expand Up @@ -396,17 +397,69 @@ contract VotingPwoerExchangeTest is Test {
}

/////// Exchange tests ///////
function testExchangeCase1() public {
function testExchangeSuccessCase() public {
bytes32 nonce = bytes32(0);
console.log(block.chainid);
console.log("Signer address:", vm.addr(dc.DEFAULT_ANVIL_KEY2()));
console.log("participant2 address:", participant2);

bytes memory signature = helper.generateSignatureFromPrivateKey(dc.DEFAULT_ANVIL_KEY2(), 1_000 * 1e18, nonce, 3600, address(votingPowerExchange));
(bytes memory signature,) = helper.generateSignatureFromPrivateKey(
dc.DEFAULT_ANVIL_KEY2(), 1_100 * 1e18, nonce, 3600, address(votingPowerExchange)
);
address signer = vm.addr(dc.DEFAULT_ANVIL_KEY2());
vm.startPrank(exchanger);
votingPowerExchange.exchange(signer, 1_100 * 1e18, nonce, 3600, signature);
vm.stopPrank();

assertEq(govToken.balanceOf(signer), 11 * 1e18);
assertEq(utilityToken.balanceOf(signer), 8_900 * 1e18);
}

function testExchangeFailCaseWhenSginatureExpired() public {
bytes32 nonce = bytes32(0);
(bytes memory signature,) = helper.generateSignatureFromPrivateKey(
dc.DEFAULT_ANVIL_KEY2(), 1_100 * 1e18, nonce, 3600, address(votingPowerExchange)
);
vm.warp(block.timestamp + 3601);
address signer = vm.addr(dc.DEFAULT_ANVIL_KEY2());
vm.startPrank(exchanger);
votingPowerExchange.exchange(signer, 1_000 * 1e18, nonce, 3600, signature);
vm.expectRevert(VotingPowerExchange.VotingPowerExchange__SignatureExpired.selector);
votingPowerExchange.exchange(signer, 1_100 * 1e18, nonce, 3600, signature);
vm.stopPrank();
}

function testExchangeFailCaseWhenSenderIsNotSigner() public {
bytes32 nonce = bytes32(0);
(bytes memory signature,) = helper.generateSignatureFromPrivateKey(
dc.DEFAULT_ANVIL_KEY2(), 1_100 * 1e18, nonce, 3600, address(votingPowerExchange)
);
address invalidSigner = makeAddr("invalidSigner");
vm.startPrank(exchanger);
bytes32 digest = createDigest(invalidSigner, 1_100 * 1e18, nonce, 3600);
vm.expectRevert(
abi.encodeWithSelector(
VotingPowerExchange.VotingPowerExchange__InvalidSignature.selector, digest, signature
)
);
votingPowerExchange.exchange(invalidSigner, 1_100 * 1e18, nonce, 3600, signature);
vm.stopPrank();
}

function createDigest(address sender, uint256 amount, bytes32 nonce, uint256 expiration)
internal
view
returns (bytes32)
{
bytes32 structHash = keccak256(abi.encode(helper._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,
address(votingPowerExchange)
)
);
return MessageHashUtils.toTypedDataHash(domainSeparator, structHash);
}
}
16 changes: 9 additions & 7 deletions test/integration/utils/VotingPowerExchangeTestHelper.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ import {VotingPowerExchange} from "src/VotingPowerExchange.sol";
import {MessageHashUtils} from "lib/openzeppelin-contracts/contracts/utils/cryptography/MessageHashUtils.sol";

contract VotingPowerExchangeTestHelper is Test {
bytes32 private constant _EXCHANGE_TYPEHASH =
bytes32 public constant _EXCHANGE_TYPEHASH =
keccak256("Exchange(address sender,uint256 amount,bytes32 nonce,uint256 expiration)");

function generateSignatureFromPrivateKey(uint256 privateKey, uint256 amount, bytes32 nonce, uint256 expiration, address exchangeAddr)
public
view
returns (bytes memory)
{
function generateSignatureFromPrivateKey(
uint256 privateKey,
uint256 amount,
bytes32 nonce,
uint256 expiration,
address exchangeAddr
) public view returns (bytes memory, bytes32) {
address sender = vm.addr(privateKey);
console.log("sender", sender);
bytes32 structHash = keccak256(abi.encode(_EXCHANGE_TYPEHASH, sender, amount, nonce, expiration));
Expand All @@ -35,6 +37,6 @@ contract VotingPowerExchangeTestHelper is Test {

(uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, hash);

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

0 comments on commit 9e1fda0

Please sign in to comment.