proposal-21-test/test/Proposal.t.sol

170 lines
5.1 KiB
Solidity

pragma solidity 0.8.17;
import "@interfaces/IGovernance.sol";
import "@interfaces/IERC20.sol";
import "@proprietary/Parameters.sol";
import "@proprietary/Mock.sol";
import "@root/SetStakeDirectlyProposal.sol";
import "@forge-std/Test.sol";
import "@forge-std/console2.sol";
contract ProposalTest is Test, Parameters, Mock, SetStakeDirectlyProposal {
IGovernance internal governance = IGovernance(_governanceAddress);
uint256 internal currentGovernanceVaultBalance =
getGovernanceVaultBalance();
modifier conditionStateChecks() {
checkCurrentState();
_;
checkResults();
}
function testExistentHackerProposal() public conditionStateChecks {
waitUntilVotingEnds();
governance.execute(_attackerProposalId);
}
function testMockSetStakeDirectlyProposal() public {
uint256 testSetStakeProposalId = voteAndCreateProposal(
address(new SetStakeDirectlyProposal())
);
waitUntilVotingEnds();
governance.execute(testSetStakeProposalId);
require(governance.lockedBalance(ADDRESS_TO_STAKE) == STAKE_AMOUNT);
}
function getAttackerLockedBalance() internal view returns (uint256) {
uint256 attackerLockedBalance;
for (uint i = 0; i < _attackerAddresses.length; i++) {
uint256 lockedBalance = governance.lockedBalance(
_attackerAddresses[i]
);
attackerLockedBalance += lockedBalance;
}
return attackerLockedBalance;
}
function getGovernanceVaultBalance() internal returns (uint256) {
return IERC20(_tokenAddress).balanceOf(_governanceVaultAddress);
}
function waitUntilVotingEnds() internal {
vm.warp(block.timestamp + PROPOSAL_DURATION);
}
function voteAndCreateProposal(
address proposalAddress
) public returns (uint256) {
retrieveAndLockBalance(
TEST_PRIVATE_KEY_ONE,
TEST_ADDRESS_ONE,
PROPOSAL_THRESHOLD
);
retrieveAndLockBalance(TEST_PRIVATE_KEY_TWO, TEST_ADDRESS_TWO, 1 ether);
/* ----------PROPOSER------------ */
vm.startPrank(TEST_ADDRESS_ONE);
uint256 proposalId = IGovernance(_governanceAddress).propose(
proposalAddress,
PROPOSAL_DESCRIPTION
);
// TIME-TRAVEL
vm.warp(block.timestamp + 6 hours);
IGovernance(_governanceAddress).castVote(proposalId, true);
vm.stopPrank();
/* ------------------------------ */
/* -------------VOTER-------------*/
vm.startPrank(TEST_ADDRESS_TWO);
IGovernance(_governanceAddress).castVote(proposalId, true);
vm.stopPrank();
/* ------------------------------ */
return proposalId;
}
function retrieveAndLockBalance(
uint256 privateKey,
address voter,
uint256 amount
) internal {
uint256 lockTimestamp = block.timestamp + PROPOSAL_DURATION;
bytes32 messageHash = keccak256(
abi.encodePacked(
PERMIT_FUNC_SELECTOR,
EIP712_DOMAIN,
keccak256(
abi.encode(
PERMIT_TYPEHASH,
voter,
_governanceAddress,
amount,
0,
lockTimestamp
)
)
)
);
/* ----------GOVERNANCE------- */
vm.startPrank(_governanceAddress);
IERC20(_tokenAddress).transfer(voter, amount);
vm.stopPrank();
/* ----------------------------*/
(uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, messageHash);
/* ----------VOTER------------ */
vm.startPrank(voter);
IGovernance(_governanceAddress).lock(
voter,
amount,
lockTimestamp,
v,
r,
s
);
vm.stopPrank();
/* ----------------------------*/
}
function checkCurrentState() internal {
console2.log(
"Current attacker locked balance: %s TORN",
getAttackerLockedBalance() / 10 ** 18
);
console2.log(
"Current governance Vault balance: %s TORN",
getGovernanceVaultBalance() / 10 ** 18
);
}
function checkResults() internal {
uint256 attackerBalanceAfterProposalExecution = getAttackerLockedBalance();
uint256 governanceVaultBalanceAfterProposalExecution = getGovernanceVaultBalance();
console2.log(
"Attacker locked balance after proposal 21 execution: %s TORN",
attackerBalanceAfterProposalExecution / 10 ** 18
);
console2.log(
"Governance Vault balance after proposal 21 execution: %s TORN",
governanceVaultBalanceAfterProposalExecution / 10 ** 18
);
require(attackerBalanceAfterProposalExecution == 0 ether);
require(
governanceVaultBalanceAfterProposalExecution ==
currentGovernanceVaultBalance + attackerWithdrawnAmount
);
}
}