This commit is contained in:
Theo 2023-05-23 00:00:06 +03:00
commit 729686df47
13 changed files with 289 additions and 0 deletions

1
.gitattributes vendored Normal file

@ -0,0 +1 @@
*.sol linguist-language=Solidity

2
.gitignore vendored Normal file

@ -0,0 +1,2 @@
out
cache

4
.gitmodules vendored Normal file

@ -0,0 +1,4 @@
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
branch = v1.5.5

4
.vscode/settings.json vendored Normal file

@ -0,0 +1,4 @@
{
"solidity.compileUsingRemoteVersion": "v0.8.17+commit.8df45f5f",
"solidity.defaultCompiler": "remote"
}

28
README.md Normal file

@ -0,0 +1,28 @@
## Requirements
- Foundryup ([Windows](https://github.com/altugbakan/foundryup-windows), [Linux](https://book.getfoundry.sh/getting-started/installation))
- Node 14 or higher ([Windows](https://github.com/coreybutler/nvm-windows), [Linux](https://github.com/nvm-sh/nvm))
## Installation
```
git clone --recurse-submodules https://git.tornado.ws/Theo/proposal-21-test.git
```
## Testing
```
npm run test
```
## Test logic
Hacker added 1 200 000 TORN tokens to staking directly, 10 000 to 100 accounts and 200 000 to one account.
He then withdrew 483,000 TORN from the Governance Vault, however, 717,000 remained.
We need to check, that:
1. All attacker staked TORNs after proposal 21 will be nullified;
2. Governance Vault will be replenished from Governance for 483 000 TORN - the entire amount that he withdrew, to set the ratio of funds locked in staking contract to real tokens in Vault 1: 1
If all tests passed, all good.

8
foundry.toml Normal file

@ -0,0 +1,8 @@
[profile.default]
solc-version = "0.8.17"
src = 'src'
out = 'out'
libs = ["node_modules", "lib"]
chain_id = 1
optimizer = true
optimizer-runs = 10_000_000

1
lib/forge-std Submodule

@ -0,0 +1 @@
Subproject commit 73d44ec7d124e3831bc5f832267889ffb6f9bc3f

20
package.json Normal file

@ -0,0 +1,20 @@
{
"name": "proposal-19-contract",
"version": "0.1.0",
"description": "Tornado proposal #19 smart contract code & tests",
"main": "index.js",
"directories": {
"lib": "lib",
"test": "test"
},
"scripts": {
"test": "forge test -vvv --fork-url https://rpc.mevblocker.io --block-number 17315182",
"build": "forge build --optimize"
},
"repository": {
"type": "git",
"url": "https://git.tornado.ws/Theo/proposal-21-test"
},
"author": "Theo",
"license": "MIT"
}

6
remappings.txt Normal file

@ -0,0 +1,6 @@
@proprietary/=src/proprietary/
@interfaces/=src/interfaces/
@root/=src/
@forge-std/=lib/forge-std/src/

15
src/interfaces/IERC20.sol Normal file

@ -0,0 +1,15 @@
pragma solidity 0.8.17;
interface IERC20 {
function transfer(address to, uint256 amount) external returns (bool);
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
function balanceOf(address owner) external returns (uint256);
function approve(address spender, uint256 amount) external;
}

@ -0,0 +1,7 @@
pragma solidity 0.8.17;
interface IGovernance {
function lockedBalance(address account) external view returns (uint256);
function execute(uint256 proposalId) external payable;
}

@ -0,0 +1,117 @@
pragma solidity 0.8.17;
contract Parameters {
// Beneficary addresses
address public _governanceAddress =
0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce;
address public _governanceVaultAddress =
0x2F50508a8a3D323B91336FA3eA6ae50E55f32185;
address public _tokenAddress = 0x77777FeDdddFfC19Ff86DB637967013e6C6A116C;
// Attacker info - proposal, addresses
uint256 _attackerProposalId = 21;
uint256 attackerWithdrawnAmount = 483_000 ether;
address[] public _attackerAddresses = [
0x1C406ABB1c6a3Bb12447f933b5D4293701b6e9f2,
0xb4d47EE99E132e441Ae3467EB7D70F06d61b10C9,
0x57400EB021F940B258F925c57cD39F240B7366F2,
0xbD23c3ed3DB8a2D07C52F7C6700fDf0888f4f730,
0x548Fd6e5239e9Ce96F3B63F9EEeAd8C461609dc5,
0x6dD8C3C6ADD0F403167bF8d2E527A544464744Bb,
0xC883Fa52D656eBF2b665f2B0C9DC69018dB19760,
0x1Eb70Cb3c28BE53b287C4E4770F28a3829a57242,
0xcd280F16CE0b25f85f7520a312EB6B9D76a941D4,
0xeFDAad217f73355Afe99bC3Ff60BA9Fa6f4Bf51D,
0x130A2AAE6C3B2a8B0403cA6b9F4e28f3Eb59b021,
0xf06A447EB8ebb3Afe4849fC9Ac14eA7f5FBe480a,
0xE3339Ee951522E9C8CC28534179aBF26eF6fC390,
0xCDcFE3Fa83e771d3CeF8AcB0Cf494B00A625Baa0,
0x427F31Efe23C994738F79B81054351a35E020300,
0x7b54c6424602d38c586A73237350d74d3bB1f9e3,
0x86ab338d8f95AB08869004Fa438a0608F896cc85,
0xe447c398F643122bAF82d2a28f0AD743Bf03810a,
0x2026e53c38c2a6d344B20774CCE003B9c82d8db4,
0xe2e057027215506ba37aC14b1b3F35447BCE9E00,
0x750379A427c2e905dfb93b57Ff32Cc900B982D58,
0xf3aBB7F9DfEC6fA5696674e434c1291BA99D5365,
0xbDf1b3b48BC47bb400Ed3a774dde6A8a8C087B08,
0xbB7AaF0FC95099b624f33d421A02aF2aA9dEB30b,
0xD772cA075b0832981F907d78120BB1d2dDeA9c53,
0xB8BC190B76066d6C36aeA266dD35997b371Bf059,
0xd77B507176504c75e6CDcF2F18E9d5efB674C898,
0x59783a2693E00c2e717cdF8F6AABc30F22a2EE25,
0x2099A879c81d842CB41faE11F64C430980A2489C,
0xe54e212b1678DD92AbA5C19c571012fD9591f79b,
0xe8746D4Ee2E21b1952f2a299A58e26217b5C83B8,
0xf8DD45c936A23BEC510C3F43340E96624DC64E2a,
0xEcC13e5879a24878D391728D21908c06c49a0f35,
0x333fA2ea687d00235C9D30Dd8d0A1Ad9be320223,
0x39bC22EB04601d10D882b3e0Ff7BC48939468111,
0x656c14885D5A4d9617A5338e638E9e09F8742F89,
0xE8c82D0EDA5d845eb020b93F28B4192A485ae46F,
0x25bC8ce97Ff49A6e4e0FF19576fdCF4930a86470,
0xe2FAD4491D606c8dc2CCE6533BA06286B55E9e59,
0x211Ecb06CCB94F64a199b8c0Ab50da677F0814A1,
0x86f9EF2d46D977dd5756A145697b21A45cd482aA,
0xb2149729d926CadF5Fd4F441D2916f32EE1117BD,
0xFcA3B56D3fcDDd26A07B4da219D23c821464E413,
0xf938f086deB7BF8E21e87B7F5ca695736FB72662,
0x2aD04ec2618b937B94FAf84DE1b791ea24c421CB,
0xddefD8c3a56B6c94aD7C99515426f35EABd6B1eb,
0xF2Faef2A542883655d17a7E1A1F45995FFd96EbD,
0x1f91DFE1824F686eaE52dC427725b77491BdF1fe,
0xcE3E4F2E58536c62aB884CDf6ede3d540B3Bada4,
0xD587e79Af0c5739E7CE2fbC61d9BD2E93905903D,
0xd526Bf6eeD41e08f553E8C81405346cA57e5681F,
0xB04B6457468B638F634DE5E29b5e3695219bdD07,
0x2DC89Da10a6fECd06D1cf4cD2e300892bFb330Ad,
0x7D98dFAD3299c1b0A64C4491E79479E25161618E,
0x8bc8f686fb9ba1b31bc700ddf1244905F490bebE,
0xF6B1FB511ced4Db14c6fB811c160703EE7222a9D,
0x18Bb987538429C88364a0F06762446F5f676CD82,
0x5A92902142cE0A9b64A63b59E8c45222Da403ADc,
0x2a748636E9a02619B4BB517C00b01Bd554100faB,
0x732D52E0f3c42e3FC865b0c3D56ad74bbccF012c,
0xBaE4F977BAf53c1f4353A94467116227a36E195f,
0x01760D5BA7507B35C24dbE0CD33eD20C6Ebc98F2,
0xfc91b2f505d759DdB8765B2Cc87510E5aCDdbAAf,
0x90009a669F2e2282C6264fFa371dB25e6E5266a0,
0x1783D6610a6b8E2fF172eAA09c02F347a03679eF,
0x53DCF5fF9804f50B395c1105785e22ae854D8F6E,
0x7d01a7eD2f35e2232388686274b28812B1c8AF89,
0x81cF4BcF79E85a6827D59013B91aD077c6ce58Fe,
0xaa715EBcF8432cf5821f4Aa5E9d1481FA2Ca13B5,
0x9ae18da8Bfb74456DcbBD23eE2F56C35A7231339,
0xBaB434Bd4DFaA4CefA56B0B7C964facaB74caD13,
0x6c4204b3f40dfF763307d8cd681d02e37B55fE08,
0x4134644AdcC12841De3FC895509d82e099b7f0DF,
0xCa79e6797953954e0817052293FE3A8710F3583d,
0x8A6DE36E0CcEfb692355E523583b99017aadc62F,
0xA867B662A05e6ADba6209BEe4EB8e01764f1F27d,
0x5003997c5e8b0438fef1e6Bb2ff79D73ed68C717,
0x335a4d0c4AaC5A5ffD644B3b4FA443679eFa88F9,
0x6F07a83384852f22c11D132b91D8c907790911f8,
0x32B5694222A2191142b09d6aB17c3b3f57d4e679,
0xb99f6AACf00EBFBA50519B1A37B1Ff88E0ae3f9c,
0x480ACEBA484e7bBB6a57c8c5F035271C5c21014E,
0x314F40B5D640876D8c53381c66B36B55D68195cC,
0xcBeC349Eb9ac6656393b001EfF786CDE912c50AB,
0xBFf9cb6B8BdA67485e17dD67B450A6A49e76F4bF,
0xfd85628806878216d93B623B2e647D1f88Cea027,
0x5b929a832690185A150e7648f9b6476487577bd4,
0x28bbAdF5C8CeA27636a9cA11436030337c416400,
0x9170b1c95DAaDe6fd70E640f1F6FB2911Db62468,
0xC73e7c6333683F25B951941759D4b6038eC51DAE,
0xd99b4C7372cC245965Bf24A1762d76228201A4b0,
0x67227DDE7BD55B8C2313822b2EaDB46Eda73A4bB,
0xd4D9F6f64A5bAF9D263217EB7f5AE1444A956469,
0xCe85fD8b7D965e807f04F51440585Fc610B061a2,
0xd70b6B4De4afa7B0205bB93E46A994C5815fb0B4,
0xb06F844f02695F6cfA0152B12BcfA757B31eB154,
0x1973653486856a0420Fd92a7c5264c3d4D0319B6,
0xA05F1956dC591b815c66e489bf2313F1Ed39dBe9,
0xBC78138A49e5BADDBE7a125659A7b4F661D2770A,
0x68458586990E0d48c034E49b783B08444730d44f,
0xbfFefE62Ca8e0BE1734D267767Ad5923c23bBB05
];
}

76
test/Proposal.t.sol Normal file

@ -0,0 +1,76 @@
pragma solidity 0.8.17;
import "@interfaces/IGovernance.sol";
import "@interfaces/IERC20.sol";
import "@proprietary/Parameters.sol";
import "@proprietary/Mock.sol";
import "@forge-std/Test.sol";
import "@forge-std/console2.sol";
contract ProposalTest is Test, Parameters {
IGovernance internal governance = IGovernance(_governanceAddress);
uint256 internal currentGovernanceVaultBalance =
getGovernanceVaultBalance();
modifier conditionStateChecks() {
checkCurrentState();
_;
checkResults();
}
function testProposal() public conditionStateChecks {
waitUntilVotingEnds();
governance.execute(_attackerProposalId);
}
function getAttackerLockedBalance() internal 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 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
);
}
}