117 lines
5.7 KiB
Solidity
117 lines
5.7 KiB
Solidity
|
// SPDX-License-Identifier: MIT
|
||
|
|
||
|
pragma solidity ^0.8.19;
|
||
|
|
||
|
import { TornadoProposalTest } from "./TornadoProposalTest.sol";
|
||
|
import { PenalisationProposal } from "@root/Proposal.sol";
|
||
|
import { IRelayerRegistry } from "@interfaces/IRelayerRegistry.sol";
|
||
|
import { IStakingRewards } from "@interfaces/IStakingRewards.sol";
|
||
|
|
||
|
import { console2 } from "@forge-std/console2.sol";
|
||
|
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||
|
|
||
|
contract TestProposal is TornadoProposalTest {
|
||
|
IRelayerRegistry internal relayerRegistry = IRelayerRegistry(getRegistryProxyAddress());
|
||
|
address[7] cheatingRelayers = [
|
||
|
0x5007565e69E5c23C278c2e976beff38eF4D27B3d, // official-tornado.eth
|
||
|
0x065f2A0eF62878e8951af3c387E4ddC944f1B8F4, // 0xtorn365.eth
|
||
|
0x18F516dD6D5F46b2875Fd822B994081274be2a8b, // torn69.eth
|
||
|
0x30F96AEF199B399B722F8819c9b0723016CEAe6C, // moon-relayer.eth
|
||
|
0xa42303EE9B2eC1DB7E2a86Ed6C24AF7E49E9e8B9, // relayer-tornado.eth
|
||
|
0x2ffAc4D796261ba8964d859867592B952b9FC158, // safe-tornado.eth
|
||
|
0xCEdac436cEA98E93F471331eCC693fF41D730921 // relayer-secure.eth
|
||
|
];
|
||
|
|
||
|
function createAndExecuteProposal() internal {
|
||
|
address currentProposalAddress = address(new PenalisationProposal());
|
||
|
uint256 currentProposalId = easyPropose(currentProposalAddress);
|
||
|
waitUntilExecutable(currentProposalId);
|
||
|
|
||
|
governance.execute(currentProposalId);
|
||
|
}
|
||
|
|
||
|
function testCheatingRelayersBalanceNullified() public {
|
||
|
for (uint8 i = 0; i < cheatingRelayers.length; i++) {
|
||
|
console2.log(
|
||
|
"Cheating relayer %s balance before penalisation: %s TORN",
|
||
|
cheatingRelayers[i],
|
||
|
relayerRegistry.getRelayerBalance(cheatingRelayers[i]) / 1e18
|
||
|
);
|
||
|
}
|
||
|
console2.log("\n");
|
||
|
|
||
|
createAndExecuteProposal();
|
||
|
|
||
|
for (uint8 i = 0; i < cheatingRelayers.length; i++) {
|
||
|
uint256 relayerBalanceAfterPenalisation = relayerRegistry.getRelayerBalance(cheatingRelayers[i]);
|
||
|
console2.log(
|
||
|
"Cheating relayer %s balance after penalisation: %s TORN", cheatingRelayers[i], relayerBalanceAfterPenalisation / 1e18
|
||
|
);
|
||
|
require(relayerBalanceAfterPenalisation == 0, "Cheating relayers balance didn't nullified");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function testHonestRelayersNotAffected() public {
|
||
|
address honestRelayerAddress = 0xa0109274F53609f6Be97ec5f3052C659AB80f012; // relayer007.eth
|
||
|
|
||
|
uint256 honestRelayerBalanceBeforeExecution = relayerRegistry.getRelayerBalance(honestRelayerAddress);
|
||
|
console2.log(
|
||
|
"Honest relayer (relayer00.eth) balance before proposal execution: %s TORN", honestRelayerBalanceBeforeExecution / 1e18
|
||
|
);
|
||
|
|
||
|
createAndExecuteProposal();
|
||
|
|
||
|
uint256 honestRelayerBalanceAfterExecution = relayerRegistry.getRelayerBalance(honestRelayerAddress);
|
||
|
console2.log("Honest relayer (relayer00.eth) balance after proposal execution: %s TORN", honestRelayerBalanceAfterExecution / 1e18);
|
||
|
|
||
|
require(honestRelayerBalanceBeforeExecution == honestRelayerBalanceAfterExecution, "Execution afftected honest relayers");
|
||
|
}
|
||
|
|
||
|
function testRelayersBalancesWithdrawedToGovernance() public {
|
||
|
uint256 governanceBalanceBeforeExecution = IERC20(getTornTokenAddress()).balanceOf(address(governance));
|
||
|
console2.log("Governance contract balance before proposal execuition: %s TORN", governanceBalanceBeforeExecution / 1e18);
|
||
|
|
||
|
uint256 expectedNullifiedAmount = (new PenalisationProposal()).getCheatingRelayersBalanceSum(cheatingRelayers);
|
||
|
|
||
|
createAndExecuteProposal();
|
||
|
|
||
|
uint256 governanceBalanceAfterExecution = IERC20(getTornTokenAddress()).balanceOf(address(governance));
|
||
|
console2.log("Governance contract balance after proposal execuition: %s TORN", governanceBalanceAfterExecution / 1e18);
|
||
|
|
||
|
require(
|
||
|
governanceBalanceAfterExecution == governanceBalanceBeforeExecution + expectedNullifiedAmount - 25_001 ether,
|
||
|
"Relayers balances isn't withdrawed"
|
||
|
);
|
||
|
}
|
||
|
|
||
|
function testBurnedCorrectAmount() public {
|
||
|
IStakingRewards staking = IStakingRewards(getStakingProxyAddress());
|
||
|
IERC20 TORN = IERC20(getTornTokenAddress());
|
||
|
|
||
|
uint256 toBurn = 678 * 1e17; // Burn 67.8 TORN
|
||
|
|
||
|
retrieveAndLockBalance(TEST_STAKER_PRIVATE_KEY, TEST_STAKER_ADDRESS, 10_000 ether);
|
||
|
uint256 stakerLockedBalance = governance.lockedBalance(TEST_STAKER_ADDRESS);
|
||
|
require(stakerLockedBalance == 10_000 ether, "Invalid test staker locked balance");
|
||
|
|
||
|
uint256 stakerRewardsBeforeBurning = staking.checkReward(TEST_STAKER_ADDRESS);
|
||
|
console2.log("Staking rewards before burning: %s", stakerRewardsBeforeBurning);
|
||
|
|
||
|
createAndExecuteProposal();
|
||
|
|
||
|
uint256 stakerRewardsAfterBurning = staking.checkReward(TEST_STAKER_ADDRESS);
|
||
|
console2.log("Staking rewards after burning 67.8 TORN: %s\n", stakerRewardsAfterBurning);
|
||
|
require(stakerRewardsAfterBurning > stakerRewardsBeforeBurning, "Rewards isn't changed after burning");
|
||
|
|
||
|
// All TORN, locked by users in Governance, is on the userVault contract balance
|
||
|
uint256 governanceLockedAmount = TORN.balanceOf(address(governance.userVault()));
|
||
|
uint256 receivedReward = stakerRewardsAfterBurning - stakerRewardsBeforeBurning;
|
||
|
uint256 expectedRewards = stakerLockedBalance * toBurn / governanceLockedAmount;
|
||
|
|
||
|
console2.log("Expected staking rewards: %s", expectedRewards);
|
||
|
console2.log("Staker received rewards: %s\n", receivedReward);
|
||
|
|
||
|
require(receivedReward == expectedRewards, "Expected and received rewards don't match");
|
||
|
}
|
||
|
}
|