Compare commits

..

16 Commits

Author SHA1 Message Date
55a6540a13 Add calculation of stakers (to who we propose to restore rewards) locked balances & use multicall, speed up scripts execution more than 10 times 2023-06-19 09:05:39 -07:00
dbd12a63a2 Add deployed contracts addresses to README 2023-06-15 20:38:55 -07:00
035ab78ac6 Update forge 2023-06-15 20:38:37 -07:00
380e7872f0 Add README 2023-06-15 14:30:30 -07:00
94b96276b6 Fix restore calculation: we should not restore rewards to those who managed to withdraw from the old Staking contract 2023-06-14 07:27:09 -07:00
d90b460355 Add tests to check correctness of staking contract functionality after proposal execution 2023-06-14 06:51:42 -07:00
808420b0d6 Add autoreturn locked tokens to Governance from test voter 2023-06-13 16:39:58 -07:00
ea9b28457c Add waiting for contracts deployment before verification 2023-06-13 12:32:09 -07:00
f2a0e18cc0 Fix merge conflicts 2023-06-13 11:37:43 -07:00
e049d9b107 Merge branch 'AlienTornadosaurusHex-main' 2023-06-13 11:33:48 -07:00
a935093f54 Add hardhat deployment by T-Hax 2023-06-13 11:33:37 -07:00
79d5bfd103 Fix rewards accrual bug mentioned by T-Hax: in 'accrueOldRewards' function we added rewards that staker hasn't earned, because 'checkReward' function in Staking contract returns updated (actual) reward amount, but not update it in storage. Replace 'checkReward' function with getter 'accumulatedRewards', which returns actual accumulated reward amount (not updated) 2023-06-12 16:45:32 -07:00
861f4cddaf Correct padding in generated Solidity proposal code 2023-06-12 15:18:32 -07:00
ed130ad30f Add hardhat dependencies & update fork-blocks 2023-06-12 15:17:52 -07:00
4a876ee7d0 Add tests (bugged) 2023-06-12 15:17:34 -07:00
AlienTornadosaurusHex
80078475d5 add hardhat deploy logic
Signed-off-by: AlienTornadosaurusHex <>
2023-06-12 19:39:42 +00:00
24 changed files with 1006 additions and 149 deletions

7
.env.example Normal file
View File

@@ -0,0 +1,7 @@
MAINNET_RPC_URL=
ETHERSCAN_KEY=
PRIVATE_KEY=
GOERLI_RPC_URL=
SEOPLIA_RPC_URL=
RINKEBY_RPC_URL=

11
.gitignore vendored
View File

@@ -3,9 +3,7 @@ cache/
out/
# Ignores development broadcast logs
!/broadcast
/broadcast/*/31337/
/broadcast/**/dry-run/
broadcast
# Docs
docs/
@@ -20,6 +18,11 @@ package-lock.json
# yarn
yarn.lock
yarn-error.log
# VScode files
.vscode
.vscode
# hh
artifacts
cache_hardhat

View File

@@ -1,3 +1,34 @@
# proposal-23-restore-rewards
# Proposal 25: restore old rewards
Proposal to restore old rewards value (as before hack) after redeploying Staking contract
Proposal to restore old rewards value (as before hack) after redeploying Staking contract to stakers, who did not have time to withdraw their rewards due to a bug
### Changes:
- Redeploying staking implementation contract to add new function `setReward`
- Restore rewards to 357 stakers (all stakers, who had more than 1 TORN in rewards at the time of the hack and didn't have time to withdraw them)
- Transfer 42 754 TORN from Governance to new Staking contract (so that stakers can withdraw their restored rewards)
### Requirements
- Rust ([Need only for Windows](https://doc.rust-lang.org/cargo/getting-started/installation.html))
- 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
```text
git clone --recurse-submodules https://git.tornado.ws/Theo/proposal-25-restore-rewards
cd proposal-25-restore-rewards
npm install
```
### Testing
```text
npm run test
```
### Contracts
1. New staking implementation contract: [etherscan link](https://etherscan.io/address/0x9c97be37840f0e754bb7adb1b16fd0954a2ba248#code)
2. Proposal contract: [etherscan link](https://etherscan.io/address/0xe3ea2661908d7ebdae01582ad77ab31eebffd365#code)

86
abi/MultiCallABI.json Normal file
View File

@@ -0,0 +1,86 @@
[
{
"constant": true,
"inputs": [],
"name": "getCurrentBlockTimestamp",
"outputs": [{ "name": "timestamp", "type": "uint256" }],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"components": [
{ "name": "target", "type": "address" },
{ "name": "callData", "type": "bytes" }
],
"name": "calls",
"type": "tuple[]"
}
],
"name": "aggregate",
"outputs": [
{ "name": "blockNumber", "type": "uint256" },
{ "name": "returnData", "type": "bytes[]" }
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getLastBlockHash",
"outputs": [{ "name": "blockHash", "type": "bytes32" }],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [{ "name": "addr", "type": "address" }],
"name": "getEthBalance",
"outputs": [{ "name": "balance", "type": "uint256" }],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getCurrentBlockDifficulty",
"outputs": [{ "name": "difficulty", "type": "uint256" }],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getCurrentBlockGasLimit",
"outputs": [{ "name": "gaslimit", "type": "uint256" }],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getCurrentBlockCoinbase",
"outputs": [{ "name": "coinbase", "type": "address" }],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [{ "name": "blockNumber", "type": "uint256" }],
"name": "getBlockHash",
"outputs": [{ "name": "blockHash", "type": "bytes32" }],
"payable": false,
"stateMutability": "view",
"type": "function"
}
]

5
config.js Normal file
View File

@@ -0,0 +1,5 @@
module.exports = {
torn: "0x77777FeDdddFfC19Ff86DB637967013e6C6A116C",
governanceProxy: "0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce",
registryProxy: "0x58E8dCC13BE9780fC42E8723D8EaD4CF46943dF2"
}

View File

@@ -1,4 +1,4 @@
Staker[385] memory stakers = [
Staker[357] memory stakers = [
Staker(0xb2C95127308876B0dA00dCE7798412bcA95C9Fee, 261_891_050_760_386_479_981),
Staker(0x52f4B90dF9560E50389107baCCD13e8BC1e5a516, 5_519_577_581_187_935_401),
Staker(0x679959449b608AF08d9419fE66D4e985c7d64D96, 6_634_938_965_540_161_678),
@@ -11,12 +11,9 @@
Staker(0x201dD47dadA5165D792e6B4bDC2600e2FC5d7375, 3_376_734_302_476_765_689),
Staker(0x97b90FBc8904F861F76CB06BFa0A465b72C5E662, 85_583_028_288_278_705_143),
Staker(0xd3660816c68EF4DB79D2cCBFA2E6D623dfD65699, 135_764_830_626_382_535_905),
Staker(0xa3a7EAe904e92fA67c1888C6572Ac884722f5288, 63_755_633_956_332_846_740),
Staker(0xBFb910652F850F85E3F85AA0C12aE8f4037095b0, 33_237_171_239_790_116_387),
Staker(0x32f8E5d3F4039d1DF89B6A1e544288289A500Fd1, 1_536_360_162_595_381_679),
Staker(0xe2506955723C01dDd6e619dD0829e28F76328c41, 72_958_648_431_519_163_392),
Staker(0x3Df488Bd07C2082E84B1CD63F343Cf3d538342bA, 107_098_359_836_630_121_582),
Staker(0x6a90E7Ba20291CDF651A6d61ebf2371BA89EF04B, 46_595_274_664_224_710_080),
Staker(0x0b7C43AF43D76f79b6f6CfBAFb3A01ddE0468225, 18_243_581_064_710_552_362),
Staker(0x524b7c9B4cA33ba72445DFd2d6404C81d8D1F2E3, 8_414_647_798_389_006_172),
Staker(0xfDEEc44b6c63E637fA3348092A9F952A02B2E695, 1_468_551_637_230_600_353),
@@ -28,17 +25,11 @@
Staker(0xB1583e01ACA426807985FAf9438c9a4cEF73B1A7, 2_769_004_780_372_765_071),
Staker(0xcDfb26F93F2D5e0F4b76190e5bC740b3A3DA16F4, 1_986_870_853_342_994_225),
Staker(0xDbcb5D2a6c77F1a8069ff686F88FC552F2F3eFCC, 2_691_179_623_359_894_955),
Staker(0x15Ed2710d0097CE9BC352Db97287bDd9104bEC92, 517_823_661_753_566_090_385),
Staker(0x85f8BeC61f75De3Dbad1bBd4CDD168ea362bDaeA, 118_525_403_763_250_297_030),
Staker(0xac57C7A3960Ba383b94b28BF44f9cdC26B84A8e7, 766_340_829_474_823_777_721),
Staker(0xEFb7Ce1357F324a324A8EABDc443b26894A2b246, 721_114_114_180_262_809_591),
Staker(0x84781094f9B11aCb35A7Dca31D731A244B25E6a4, 389_646_430_287_742_483_283),
Staker(0xA3A89931799Ba449A7bd1658EfD9C8662dd22BcA, 4_471_048_279_368_398_062),
Staker(0x13e50a5e7D695ae729Da77623c61661B27A3b60a, 25_552_108_041_996_067_156),
Staker(0xeafA9AA6832c076D5af3d58D9224E218CA074f04, 3_278_339_837_838_322_677),
Staker(0x25713B024a8004727Ba79c43647a77c7447948dB, 16_833_083_830_815_723_474),
Staker(0x73D23cDaBBb25B0E039470ea940514Ca30744277, 6_268_058_376_469_446_863),
Staker(0x11FD8380FcEF61E7D1FC054d4Ba20D7230a5593A, 241_999_616_776_245_144_340),
Staker(0xB157ba30e3467DdBC844f14F02b4ba741f1d549F, 65_080_791_858_799_563_574),
Staker(0xB6dA1D0cac0CAC8d39125d5213E1623750525ed5, 3_582_972_520_064_518_922),
Staker(0xEBf919b0DAfb9ea4BF324108A142C64A69052D8f, 1_492_116_146_713_012_865_552),
@@ -47,7 +38,6 @@
Staker(0x076b499e9191A29Fa9210e497cBd89DABC878B6E, 4_403_836_602_105_176_579),
Staker(0x83c418D2eD6670785330B996b47a18492b61e218, 2_423_008_690_534_464_349_496),
Staker(0xcD37EF9120132F71E23982881e19B68aE3B4E871, 6_094_554_447_886_213_907),
Staker(0xe44799Ef334Df157e0F8e2855E5EbeBdBc02b299, 498_687_077_665_731_358_140),
Staker(0xff36EdACcEebADC368ea6CACA13E5f3bBD1b43AC, 1_685_473_922_303_763_108),
Staker(0x312044825EB5CD2C4Bb016a7a86ce32240Af9136, 27_126_619_039_727_679_328),
Staker(0x3035A1bBd824041B07f8Ab2297a71A81E00127c5, 14_756_069_076_031_120_181),
@@ -60,8 +50,6 @@
Staker(0xF99d1946Bf038a1205d430Ec91401E760e5F8F6F, 8_151_047_628_859_550_523_186),
Staker(0x9897Bc7231492CDf163BB81bFF10A5919a73d132, 3_388_092_111_567_580_393_688),
Staker(0x8953C798a6F54ea8907875c51e5D466DE76A1b26, 797_098_747_089_744_161_355),
Staker(0x9C42EBDf0fA6fA0274aEEBf981613Dfa9c99BFF8, 1_151_021_932_914_438_641_249),
Staker(0xD88189f7Dee6E5DBd6cbC6F06FD357f4Bf7f330b, 1_435_829_849_735_697_778_451),
Staker(0xf4DcA9B37f09D15f8dF740055cEaA860912efe2C, 2_569_990_661_510_076_867),
Staker(0xAdE9e51C9E23d64E538A7A38656B78aB6Bcc349e, 146_771_928_128_749_080_734),
Staker(0xeE1D1ac27A80De54F0ba92b2E25EBb3418495db2, 2_943_758_390_988_392_723),
@@ -147,13 +135,11 @@
Staker(0x48Ef3De608AB2304dBB0c4497d266F3BF5506e7B, 1_346_590_027_777_001_145),
Staker(0x3716905b040D5cd8a7DdE784918199117d72c3B3, 1_400_844_245_925_263_369),
Staker(0xB835b4e277094D4AF9Fbb66e9f5Db9e6E8dC65dB, 25_683_271_096_264_423_274),
Staker(0x08d19484246a987411e04a7F098E36F92cad4f24, 20_246_123_092_729_700_406),
Staker(0x42DbF634c256acd17beDDC1330488F1BEa7B8BDf, 319_523_008_529_625_373_272),
Staker(0xE7304bA0f157f2Ade94015934284b6704BC72911, 39_826_654_578_302_448_107),
Staker(0xE06bF8125273Ead3814aBDE0D548079991F5DD8a, 22_645_804_997_633_317_877),
Staker(0xaa9298F0c3e97DdA6277713fd3Ed6e2A389E7260, 3_572_475_984_033_907_702),
Staker(0xC9D32C7e16d71aF1739618356F1e3F2c69e8784a, 2_812_672_628_757_140_199),
Staker(0xFF30D836794Bfe71E888A7aa2AB62BfFb3F7a73a, 23_218_272_203_140_765_926),
Staker(0xCcC24DD1FE711d9f47A42a04b16b789669A21C98, 252_786_587_455_637_451_074),
Staker(0x0091a0aAF911A27133713028a83644224FcD7103, 4_391_483_020_114_108_858),
Staker(0x74E5B46a2A39F86ECc8CABCc409556953A688484, 3_576_335_685_734_120_104),
@@ -211,7 +197,6 @@
Staker(0xc8d51E5a9293426d678400f05fDF8395fFE34187, 1_159_086_427_507_011_821),
Staker(0x1CE7DC66CC98c61A573105514d073D64a9a8608f, 26_389_224_886_673_669_669),
Staker(0xD3069f6050A3dd4ECCc27b6A66E5C401aB59DeD5, 1_131_703_913_861_582_424_146),
Staker(0xC796A650D6e7869D1c22642Bf0a4c7D5b3bbed32, 6_099_909_659_507_227_766),
Staker(0xc6DFfE2C1C910A3E049b29638bE0286645054f3C, 29_472_347_834_775_340_843),
Staker(0x2753dEeD6Fc665ff159c94aEAFb8a19E4525831E, 25_294_315_679_682_630_786),
Staker(0x0d4E989c7620C8749c9417d2BF218896C767B606, 3_364_398_457_228_954_809_190),
@@ -224,7 +209,6 @@
Staker(0x24f04EC62597C11752c47448228B63052ED3158a, 90_815_074_343_246_091_464),
Staker(0xA11109126af2c5904fdc5b6203108Fef5770E85E, 17_491_569_071_641_631_106),
Staker(0x8904FFC6Aa039dB5941De11309a42372F3F7D2FD, 89_018_897_961_346_317_265),
Staker(0x95Be36B3F6a5DC958c59a4a81FdF0BEE671f26F3, 92_179_556_551_282_444_104),
Staker(0xa729adDeFe1fa7BCe87053ed55D55EDdDD13De60, 21_709_183_619_942_034_343),
Staker(0x409ac9C16B2CD569EC06bb9eceF97eeFDe0e8054, 15_006_870_038_073_374_755),
Staker(0xdF3c8E63677C79b24608bDed80CeD65667513BcB, 541_718_227_741_233_200_336),
@@ -257,7 +241,6 @@
Staker(0x26D3b88d464A575784Be70Edc5F9290dC5e296DB, 143_520_553_783_208_184_300),
Staker(0x4ffc1A4bD191935C603df061065Ce97C25C70687, 1_104_677_208_403_973_125),
Staker(0x7Abbdbd51813d85B448F887b946719Dd2B09D6F7, 28_496_157_399_564_678_982),
Staker(0xEb89EfE3Ed80288E310c5529e1E242b4ab56E196, 10_158_103_172_727_951_367),
Staker(0x3C7ddEB357e4341A18cfC587343a4463a280B9c5, 15_766_263_220_154_597_250),
Staker(0x8633ADAf2438703d6D7f953829A4fe0c95FbeC44, 14_574_784_535_592_207_846),
Staker(0xAD142B79f2500Bf194C174f06C7dC901A2CdA74f, 7_123_937_386_942_958_617),
@@ -285,7 +268,6 @@
Staker(0x16eb5Fbb2a5c7dAbC2c7688482378e89471d5724, 56_528_851_406_540_169_265),
Staker(0x356eE97D7D560af2E97E9f9EEe56b2e09D60e6F5, 2_357_571_123_330_435_682_004),
Staker(0x000AD8F56D3408abE29466189612d1B7B19E4420, 8_944_601_804_979_063_344),
Staker(0xc82ceD242a7c064EC0ef3742BDea830aEB46D614, 225_374_382_403_472_958_564),
Staker(0xAd412239848f37a5dDb8fAbb523D05F4FFdB2651, 1_852_483_360_172_530_551),
Staker(0x21c756E2c7B898BDa8a3b2A77e4C56D855Ab9414, 52_258_855_596_837_389_305),
Staker(0xa6Ba7cddc1c4fBfFBA96eCE341F9baA1c35fA76e, 10_324_733_292_812_452_226),
@@ -320,14 +302,12 @@
Staker(0xA103c48Dbe3E804C23a98C5f159cEb3305c28E7b, 3_039_820_725_899_735_674),
Staker(0xab03945BC97F6899902D4296Ff97cAE8dbdc1A11, 66_797_846_279_254_338_952),
Staker(0xB945e8074C3e2F758B045Cb9a30066EE33CDB87E, 8_960_852_709_660_572_526),
Staker(0xDEB1c51514ee12d9F76Eb67AfCb7B4c33B466449, 8_131_473_545_148_842_396),
Staker(0x00377B2FC0044Dec6507855eDd6531aF1755cCe4, 187_316_100_663_496_504_711),
Staker(0xDaABa4C3a3026149a7a811bcb4B4EE9F23B61800, 1_342_110_570_226_429_076),
Staker(0x10aab4B0EF76AA2AC9b5909e671517a1171B050E, 9_816_488_209_589_379_461),
Staker(0xD9D10dc5609d77F2A15FAa68414835A6ed19269B, 95_363_084_515_727_944_710),
Staker(0x71e989dC58c879D26C2efDce097edeE505A57a28, 2_088_864_348_657_925_026),
Staker(0xdF20a1124d6B44e19ad75675a622d9c9669E59B6, 88_352_293_222_343_728_212),
Staker(0xaA8B1a05dF753F54DE787a752cB9E7808f447820, 23_946_074_798_869_806_567),
Staker(0x7E5c540b343fB854782617dECc82FBc1745b5591, 14_767_739_390_099_031_589),
Staker(0x209D49fda266C0AB257648555f8459F90e154aEd, 129_761_028_103_842_230_426),
Staker(0xF4d2D64D1f9190A9daB0960c80e5C73c04710184, 20_259_718_574_398_138_635),
@@ -356,11 +336,7 @@
Staker(0xea76eE7035aF65410D290cB7E2Ed8Fc01C395266, 6_866_348_488_289_388_870),
Staker(0xC2e6B265cb965DED721566f0f9Eb5ab1A6162A21, 22_971_027_302_959_450_151),
Staker(0x4d6A11EbEC10E133A5007578Ad792F765ED724F2, 1_523_390_814_593_599_013_009),
Staker(0xaF305fEfDc439cb1CA9FAC2f9d271fD2CC7B3F05, 34_558_215_533_487_668_461),
Staker(0x164f9ECFc5Ec74fAC1Ba1ca28E71Fd57FeadCD27, 43_630_581_854_870_958_303),
Staker(0xddbc1841BE23b2ab55501Deb4d6bc39E3f8AA2d7, 57_697_184_564_150_419_473),
Staker(0x7b5edF38D955dd9deC103aF05c2D68B28e02Ad90, 990_145_869_312_977_038_005),
Staker(0xE4143f6377AEcd7193b9731d1C28815b57C4f5Ab, 794_513_313_076_462_735_653),
Staker(0x9Fd4d0dE8A3A8a8F2aC003A5ece295CE9512d9c6, 36_016_585_133_757_988_164),
Staker(0x3390937ec4D4b94002BCacf65D2F98594b4980eF, 6_453_311_584_351_983_424),
Staker(0xA207ac236dFdeE6F885d0Cc1D0C8100b46fA91EE, 1_450_736_948_351_239_615),
@@ -369,12 +345,9 @@
Staker(0xc71cB68d38dF4E2190128DCb7E39bD1e72Fc3A2F, 13_498_777_595_192_377_744),
Staker(0x3E40eCBf8eB74fB708b8cCeA28c1C9312697aFDd, 2_547_293_201_582_353_144),
Staker(0x1e4d844528F3C9890bE6c3de38Dc8c695Cd06B20, 27_853_939_827_678_230_227),
Staker(0x45a4a7b51f8691Bd52988d8ee3f01F7518f6B056, 11_167_199_970_888_954_708),
Staker(0x4BF646757dA7067E683EB20cD122AfFBc0E67e39, 4_512_233_232_588_903_004),
Staker(0xb6242d8F02bA15917A84bD83C2eeee0e45288a03, 9_403_472_182_706_909_584),
Staker(0x6f4CbC2E042ed0D1Df4bf14d00eEb52Ff1E0e5F8, 9_748_334_349_185_074_783),
Staker(0x92374BA66EE27f207F9efff0837FF6D707006304, 58_838_358_111_071_620_908),
Staker(0x6dF07d3864c5F7ee564B5920199374C0b864E7d6, 664_290_901_673_954_681_162),
Staker(0x04700e0Ef1bCD91d36e7CE63FE93d651DFB272cA, 13_074_452_933_044_923_946),
Staker(0x8a1d5F23566c802CccEF7f02d5f216c37c8e44aD, 1_481_488_396_230_202_148),
Staker(0xfa2176D82cbA00d54998E6C37616b75ceCef08a0, 8_723_821_105_751_268_318),
@@ -382,12 +355,11 @@
Staker(0x592340957eBC9e4Afb0E9Af221d06fDDDF789de9, 3_571_261_202_347_432_870),
Staker(0x000000Cd6521Ed1a65FAe0678eA15aF4EEAD74fe, 1_431_414_111_205_873_746),
Staker(0xC49415493eB3Ec64a0F13D8AA5056f1CfC4ce35c, 1_213_791_173_344_605_522),
Staker(0xa6eDC956290b7Ce416c5d8EDc67E1C32506Fe099, 366_757_732_355_918_570_636),
Staker(0xbd0fac9A19E8E19F6245eD20411E22D4786752c8, 4_355_144_205_984_655_655)
];
for (uint64 i = 0; i < stakers.length; i++){
accrueOldReward(stakers[i].addr, stakers[i].oldRewards);
}
IERC20(tornAddress).transfer(stakingProxyAddress, 51_038_101_771_805_874_869_526);
IERC20(tornAddress).transfer(stakingProxyAddress, 42_754_780_712_309_224_285_728);

View File

@@ -0,0 +1 @@
Locked balance of stakers to who we want restore rewards: 392252226884126520706939 (~ 392252.23 TORN)

View File

@@ -5,7 +5,7 @@ out = 'out'
libs = ["node_modules", "lib"]
# Compiler
auto_detect_solc = true
solc = "0.6.12"
via_ir = true
optimizer = true
optimizer-runs = 200

76
hardhat.config.js Normal file
View File

@@ -0,0 +1,76 @@
require('dotenv').config()
require('@nomicfoundation/hardhat-foundry')
require('@nomicfoundation/hardhat-verify')
require('@nomiclabs/hardhat-ethers')
/**
* @type import('hardhat/config').HardhatUserConfig
*/
module.exports = {
solidity: {
compilers: [
{
version: '0.6.2',
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},
{
version: '0.6.12',
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},
],
},
networks: {
hardhat: {
forking: {
url: `${process.env.MAINNET_RPC_URL}`,
},
chainId: 1,
loggingEnabled: false,
allowUnlimitedContractSize: false,
},
rinkeby: {
url: `${process.env.RINKEBY_RPC_URL}`,
accounts: `${process.env.PRIVATE_KEY}`
? [`${process.env.PRIVATE_KEY}`]
: { mnemonic: 'test test test test test junk' },
},
goerli: {
url: `${process.env.GOERLI_RPC_URL}`,
accounts: `${process.env.PRIVATE_KEY}`
? [`${process.env.PRIVATE_KEY}`]
: { mnemonic: 'test test test test test junk' },
},
sepolia: {
url: `${process.env.SEPOLIA_RPC_URL}`,
accounts: `${process.env.PRIVATE_KEY}`
? [`${process.env.PRIVATE_KEY}`]
: { mnemonic: 'test test test test test junk' },
},
mainnet: {
url: `${process.env.MAINNET_RPC_URL}`,
accounts: `${process.env.PRIVATE_KEY}`
? [`${process.env.PRIVATE_KEY}`]
: { mnemonic: 'test test test test test junk' },
},
},
mocha: {
timeout: 9999999999 /* The following simply does not work: ignore: ["factory.with.registry.test.js", "sidechain.instance.factory.test.js"] */,
},
spdxLicenseIdentifier: {
overwrite: true,
runOnCompile: true,
},
etherscan: {
apiKey: `${process.env.ETHERSCAN_KEY}`,
},
}

View File

@@ -1,29 +1,38 @@
{
"name": "proposal-25-restore-rewards",
"version": "1.0.0",
"description": "Proposal to restore old rewards value (as before hack) after redeploying Staking contract",
"scripts": {
"computeRewards": "npx ts-node scripts/writeStakersData.ts",
"test": "forge test -vvv --fork-url https://rpc.mevblocker.io --fork-block-number 17414821",
"testGas": "forge test -vvv --fork-url https://rpc.mevblocker.io --fork-block-number 17414821 --gas-report"
},
"repository": {
"type": "git",
"url": "https://git.tornado.ws/Theo/proposal-25-restore-rewards"
},
"author": "Theo",
"license": "MIT",
"dependencies": {
"bignumber.js": "^9.1.1",
"dotenv": "^16.1.3",
"web3": "^1.10.0",
"web3-utils": "^1.10.0",
"@openzeppelin/contracts": "^3.2.0-rc.0",
"@openzeppelin/upgrades-core": "^1.0.1",
"torn-token": "^1.0.4"
},
"devDependencies": {
"ts-node": "^10.9.1",
"typescript": "^5.1.3"
}
"name": "proposal-25-restore-rewards",
"version": "1.0.0",
"description": "Proposal to restore old rewards value (as before hack) after redeploying Staking contract",
"scripts": {
"computeRewards": "npx ts-node scripts/writeStakersData.ts",
"test": "forge test -vvv --fork-url https://rpc.mevblocker.io --fork-block-number 17466009",
"testGas": "forge test -vvv --fork-url https://rpc.mevblocker.io --gas-report",
"testStakersLocked": "npx ts-node test/stakersLockedBalanceSum.ts"
},
"repository": {
"type": "git",
"url": "https://git.tornado.ws/Theo/proposal-25-restore-rewards"
},
"author": "Theo",
"license": "MIT",
"dependencies": {
"@openzeppelin/contracts": "^3.2.0-rc.0",
"@openzeppelin/upgrades-core": "^1.0.1",
"bignumber.js": "^9.1.1",
"dotenv": "^16.1.4",
"torn-token": "^1.0.4",
"web3": "^1.10.0",
"web3-utils": "^1.10.0"
},
"devDependencies": {
"@nomiclabs/hardhat-ethers": "^2.2.3",
"@nomiclabs/hardhat-waffle": "^2.0.6",
"chai": "^4.3.7",
"ethereum-waffle": "^4.0.10",
"ethers": "^5",
"@nomicfoundation/hardhat-foundry": "^1.0.1",
"@nomicfoundation/hardhat-verify": "^1.0.1",
"hardhat": "^2.15.0",
"ts-node": "^10.9.1",
"typescript": "^5.1.3"
}
}

48
scripts/deployProposal.js Normal file
View File

@@ -0,0 +1,48 @@
const hre = require("hardhat");
const config = require("../config");
const { ethers } = hre;
const sleep = (s) => new Promise((r) => setTimeout(r, s * 1000));
async function main() {
const factory_staking = await ethers.getContractFactory(
"TornadoStakingRewards"
);
const factory_proposal = await ethers.getContractFactory(
"RestoreRewardsProposal"
);
const staking = await factory_staking.deploy(
config.governanceProxy,
config.torn,
config.registryProxy
);
await sleep(20);
console.log(
"\nStaking contract impl successfully deployed @ " + staking.target + "\n"
);
await hre.run("verify:verify", {
address: staking.target,
constructorArguments: [
config.governanceProxy,
config.torn,
config.registryProxy,
],
});
const proposal = await factory_proposal.deploy(staking.target);
await sleep(20);
console.log(
"\nProposal 25 successfully deployed @ " + proposal.target + "\n"
);
await hre.run("verify:verify", {
address: proposal.target,
constructorArguments: [staking.target],
});
}
main().then((res) => console.log(res ?? "\nScript finished.\n"));

View File

@@ -1,36 +1,41 @@
import fs from 'fs';
import fs from "fs";
import path from "path";
import BigNumber from "bignumber.js";
import { getStakersWithRewardsBeforeHack } from '../utils/stakers';
import { getStakersWithRewardsBeforeHack, getStakersWithdrawedAfterHack } from "../utils/stakers";
// Format options for BigNumber printing
const fmt = {
prefix: '',
decimalSeparator: '.',
groupSeparator: '_',
prefix: "",
decimalSeparator: ".",
groupSeparator: "_",
groupSize: 3,
secondaryGroupSize: 0,
fractionGroupSeparator: ' ',
fractionGroupSeparator: " ",
fractionGroupSize: 0,
suffix: ''
}
suffix: "",
};
BigNumber.config({ FORMAT: fmt });
async function main() {
// All stakers who had more than 1 TORN in rewards at the time of the hack
const stakersWithRewardsBeforeHack = await getStakersWithRewardsBeforeHack();
// Stakers who withdrew rewards from the time of hack until the balance of the old Staking contract was nullified
const stakersWithdrawedAfterHack = await getStakersWithdrawedAfterHack();
const rewardsSum = stakersWithRewardsBeforeHack.reduce((acc, staker) => acc.plus(staker.rewardBalance), BigNumber(0));
// It makes no sense to restore awards to those who already withdrew them from the old Staking contract
const stakersToRestoreRewards = stakersWithRewardsBeforeHack.filter((staker) => !stakersWithdrawedAfterHack.includes(staker.address));
const stakersDisplayedInfo = stakersWithRewardsBeforeHack.map((staker) => {
return `${staker.address} = ${staker.rewardBalance.toString(10)} (~ ${staker.rewardBalance.div(1e18).toFixed(2)} TORN)`;
});
fs.writeFileSync(path.join("data", "rewardsBeforeHack.txt"), stakersDisplayedInfo.join("\n"));
const rewardsSum = stakersToRestoreRewards.reduce((acc, staker) => acc.plus(staker.rewardBalance), BigNumber(0));
console.log("Sum of rewards before hack:", rewardsSum.div(1e18).toFixed(2), "TORN");
const stakersDisplayedInfo = stakersWithRewardsBeforeHack.map(staker => {
return `${staker.address} = ${staker.rewardBalance.toString(10)} (~ ${staker.rewardBalance.div(1e18).toFixed(2)} TORN)`;
})
fs.writeFileSync(path.join("data", "rewardsBeforeHack.txt"), stakersDisplayedInfo.join('\n'));
const stakersData = stakersWithRewardsBeforeHack.map(staker => {
return `Staker(${staker.address}, ${staker.rewardBalance.toFormat()})`
const stakersData = stakersToRestoreRewards.map((staker) => {
return `Staker(${staker.address}, ${staker.rewardBalance.toFormat()})`;
});
const commandToAccrueRewards = `accrueOldReward(stakers[i].addr, stakers[i].oldRewards);`;
const commandToReplenishStaking = `IERC20(tornAddress).transfer(stakingProxyAddress, ${rewardsSum.toFormat()});`;
@@ -38,7 +43,7 @@ async function main() {
const codePadding3 = " ".repeat(12);
const codeToAccrueRewards =
codePadding2 +
`Staker[${stakersWithRewardsBeforeHack.length}] memory stakers = [\n` +
`Staker[${stakersToRestoreRewards.length}] memory stakers = [\n` +
codePadding3 +
stakersData.join(`,\n${codePadding3}`) +
`\n${codePadding2}];\n\n` +
@@ -46,12 +51,10 @@ async function main() {
`for (uint64 i = 0; i < stakers.length; i++){\n` +
`${codePadding3}` +
commandToAccrueRewards +
`\n${codePadding2}}\n` +
`\n${codePadding2}}\n\n` +
codePadding2 +
'\n' +
commandToReplenishStaking;
fs.writeFileSync(path.join("data", "codeToAccrueRewards.txt"), codeToAccrueRewards);
}
main();
main();

View File

@@ -22,13 +22,13 @@ contract RestoreRewardsProposal {
function accrueOldReward(address stakerAddress, uint256 oldRewards) internal {
ITornadoStakingRewards staking = ITornadoStakingRewards(stakingProxyAddress);
staking.setReward(stakerAddress, staking.checkReward(stakerAddress) + oldRewards);
staking.setReward(stakerAddress, staking.accumulatedRewards(stakerAddress) + oldRewards);
}
function executeProposal() external {
AdminUpgradeableProxy(payable(stakingProxyAddress)).upgradeTo(deployedStakingImplementationAddress);
Staker[385] memory stakers = [
Staker[357] memory stakers = [
Staker(0xb2C95127308876B0dA00dCE7798412bcA95C9Fee, 261_891_050_760_386_479_981),
Staker(0x52f4B90dF9560E50389107baCCD13e8BC1e5a516, 5_519_577_581_187_935_401),
Staker(0x679959449b608AF08d9419fE66D4e985c7d64D96, 6_634_938_965_540_161_678),
@@ -41,12 +41,9 @@ contract RestoreRewardsProposal {
Staker(0x201dD47dadA5165D792e6B4bDC2600e2FC5d7375, 3_376_734_302_476_765_689),
Staker(0x97b90FBc8904F861F76CB06BFa0A465b72C5E662, 85_583_028_288_278_705_143),
Staker(0xd3660816c68EF4DB79D2cCBFA2E6D623dfD65699, 135_764_830_626_382_535_905),
Staker(0xa3a7EAe904e92fA67c1888C6572Ac884722f5288, 63_755_633_956_332_846_740),
Staker(0xBFb910652F850F85E3F85AA0C12aE8f4037095b0, 33_237_171_239_790_116_387),
Staker(0x32f8E5d3F4039d1DF89B6A1e544288289A500Fd1, 1_536_360_162_595_381_679),
Staker(0xe2506955723C01dDd6e619dD0829e28F76328c41, 72_958_648_431_519_163_392),
Staker(0x3Df488Bd07C2082E84B1CD63F343Cf3d538342bA, 107_098_359_836_630_121_582),
Staker(0x6a90E7Ba20291CDF651A6d61ebf2371BA89EF04B, 46_595_274_664_224_710_080),
Staker(0x0b7C43AF43D76f79b6f6CfBAFb3A01ddE0468225, 18_243_581_064_710_552_362),
Staker(0x524b7c9B4cA33ba72445DFd2d6404C81d8D1F2E3, 8_414_647_798_389_006_172),
Staker(0xfDEEc44b6c63E637fA3348092A9F952A02B2E695, 1_468_551_637_230_600_353),
@@ -58,17 +55,11 @@ contract RestoreRewardsProposal {
Staker(0xB1583e01ACA426807985FAf9438c9a4cEF73B1A7, 2_769_004_780_372_765_071),
Staker(0xcDfb26F93F2D5e0F4b76190e5bC740b3A3DA16F4, 1_986_870_853_342_994_225),
Staker(0xDbcb5D2a6c77F1a8069ff686F88FC552F2F3eFCC, 2_691_179_623_359_894_955),
Staker(0x15Ed2710d0097CE9BC352Db97287bDd9104bEC92, 517_823_661_753_566_090_385),
Staker(0x85f8BeC61f75De3Dbad1bBd4CDD168ea362bDaeA, 118_525_403_763_250_297_030),
Staker(0xac57C7A3960Ba383b94b28BF44f9cdC26B84A8e7, 766_340_829_474_823_777_721),
Staker(0xEFb7Ce1357F324a324A8EABDc443b26894A2b246, 721_114_114_180_262_809_591),
Staker(0x84781094f9B11aCb35A7Dca31D731A244B25E6a4, 389_646_430_287_742_483_283),
Staker(0xA3A89931799Ba449A7bd1658EfD9C8662dd22BcA, 4_471_048_279_368_398_062),
Staker(0x13e50a5e7D695ae729Da77623c61661B27A3b60a, 25_552_108_041_996_067_156),
Staker(0xeafA9AA6832c076D5af3d58D9224E218CA074f04, 3_278_339_837_838_322_677),
Staker(0x25713B024a8004727Ba79c43647a77c7447948dB, 16_833_083_830_815_723_474),
Staker(0x73D23cDaBBb25B0E039470ea940514Ca30744277, 6_268_058_376_469_446_863),
Staker(0x11FD8380FcEF61E7D1FC054d4Ba20D7230a5593A, 241_999_616_776_245_144_340),
Staker(0xB157ba30e3467DdBC844f14F02b4ba741f1d549F, 65_080_791_858_799_563_574),
Staker(0xB6dA1D0cac0CAC8d39125d5213E1623750525ed5, 3_582_972_520_064_518_922),
Staker(0xEBf919b0DAfb9ea4BF324108A142C64A69052D8f, 1_492_116_146_713_012_865_552),
@@ -77,7 +68,6 @@ contract RestoreRewardsProposal {
Staker(0x076b499e9191A29Fa9210e497cBd89DABC878B6E, 4_403_836_602_105_176_579),
Staker(0x83c418D2eD6670785330B996b47a18492b61e218, 2_423_008_690_534_464_349_496),
Staker(0xcD37EF9120132F71E23982881e19B68aE3B4E871, 6_094_554_447_886_213_907),
Staker(0xe44799Ef334Df157e0F8e2855E5EbeBdBc02b299, 498_687_077_665_731_358_140),
Staker(0xff36EdACcEebADC368ea6CACA13E5f3bBD1b43AC, 1_685_473_922_303_763_108),
Staker(0x312044825EB5CD2C4Bb016a7a86ce32240Af9136, 27_126_619_039_727_679_328),
Staker(0x3035A1bBd824041B07f8Ab2297a71A81E00127c5, 14_756_069_076_031_120_181),
@@ -90,8 +80,6 @@ contract RestoreRewardsProposal {
Staker(0xF99d1946Bf038a1205d430Ec91401E760e5F8F6F, 8_151_047_628_859_550_523_186),
Staker(0x9897Bc7231492CDf163BB81bFF10A5919a73d132, 3_388_092_111_567_580_393_688),
Staker(0x8953C798a6F54ea8907875c51e5D466DE76A1b26, 797_098_747_089_744_161_355),
Staker(0x9C42EBDf0fA6fA0274aEEBf981613Dfa9c99BFF8, 1_151_021_932_914_438_641_249),
Staker(0xD88189f7Dee6E5DBd6cbC6F06FD357f4Bf7f330b, 1_435_829_849_735_697_778_451),
Staker(0xf4DcA9B37f09D15f8dF740055cEaA860912efe2C, 2_569_990_661_510_076_867),
Staker(0xAdE9e51C9E23d64E538A7A38656B78aB6Bcc349e, 146_771_928_128_749_080_734),
Staker(0xeE1D1ac27A80De54F0ba92b2E25EBb3418495db2, 2_943_758_390_988_392_723),
@@ -177,13 +165,11 @@ contract RestoreRewardsProposal {
Staker(0x48Ef3De608AB2304dBB0c4497d266F3BF5506e7B, 1_346_590_027_777_001_145),
Staker(0x3716905b040D5cd8a7DdE784918199117d72c3B3, 1_400_844_245_925_263_369),
Staker(0xB835b4e277094D4AF9Fbb66e9f5Db9e6E8dC65dB, 25_683_271_096_264_423_274),
Staker(0x08d19484246a987411e04a7F098E36F92cad4f24, 20_246_123_092_729_700_406),
Staker(0x42DbF634c256acd17beDDC1330488F1BEa7B8BDf, 319_523_008_529_625_373_272),
Staker(0xE7304bA0f157f2Ade94015934284b6704BC72911, 39_826_654_578_302_448_107),
Staker(0xE06bF8125273Ead3814aBDE0D548079991F5DD8a, 22_645_804_997_633_317_877),
Staker(0xaa9298F0c3e97DdA6277713fd3Ed6e2A389E7260, 3_572_475_984_033_907_702),
Staker(0xC9D32C7e16d71aF1739618356F1e3F2c69e8784a, 2_812_672_628_757_140_199),
Staker(0xFF30D836794Bfe71E888A7aa2AB62BfFb3F7a73a, 23_218_272_203_140_765_926),
Staker(0xCcC24DD1FE711d9f47A42a04b16b789669A21C98, 252_786_587_455_637_451_074),
Staker(0x0091a0aAF911A27133713028a83644224FcD7103, 4_391_483_020_114_108_858),
Staker(0x74E5B46a2A39F86ECc8CABCc409556953A688484, 3_576_335_685_734_120_104),
@@ -241,7 +227,6 @@ contract RestoreRewardsProposal {
Staker(0xc8d51E5a9293426d678400f05fDF8395fFE34187, 1_159_086_427_507_011_821),
Staker(0x1CE7DC66CC98c61A573105514d073D64a9a8608f, 26_389_224_886_673_669_669),
Staker(0xD3069f6050A3dd4ECCc27b6A66E5C401aB59DeD5, 1_131_703_913_861_582_424_146),
Staker(0xC796A650D6e7869D1c22642Bf0a4c7D5b3bbed32, 6_099_909_659_507_227_766),
Staker(0xc6DFfE2C1C910A3E049b29638bE0286645054f3C, 29_472_347_834_775_340_843),
Staker(0x2753dEeD6Fc665ff159c94aEAFb8a19E4525831E, 25_294_315_679_682_630_786),
Staker(0x0d4E989c7620C8749c9417d2BF218896C767B606, 3_364_398_457_228_954_809_190),
@@ -254,7 +239,6 @@ contract RestoreRewardsProposal {
Staker(0x24f04EC62597C11752c47448228B63052ED3158a, 90_815_074_343_246_091_464),
Staker(0xA11109126af2c5904fdc5b6203108Fef5770E85E, 17_491_569_071_641_631_106),
Staker(0x8904FFC6Aa039dB5941De11309a42372F3F7D2FD, 89_018_897_961_346_317_265),
Staker(0x95Be36B3F6a5DC958c59a4a81FdF0BEE671f26F3, 92_179_556_551_282_444_104),
Staker(0xa729adDeFe1fa7BCe87053ed55D55EDdDD13De60, 21_709_183_619_942_034_343),
Staker(0x409ac9C16B2CD569EC06bb9eceF97eeFDe0e8054, 15_006_870_038_073_374_755),
Staker(0xdF3c8E63677C79b24608bDed80CeD65667513BcB, 541_718_227_741_233_200_336),
@@ -287,7 +271,6 @@ contract RestoreRewardsProposal {
Staker(0x26D3b88d464A575784Be70Edc5F9290dC5e296DB, 143_520_553_783_208_184_300),
Staker(0x4ffc1A4bD191935C603df061065Ce97C25C70687, 1_104_677_208_403_973_125),
Staker(0x7Abbdbd51813d85B448F887b946719Dd2B09D6F7, 28_496_157_399_564_678_982),
Staker(0xEb89EfE3Ed80288E310c5529e1E242b4ab56E196, 10_158_103_172_727_951_367),
Staker(0x3C7ddEB357e4341A18cfC587343a4463a280B9c5, 15_766_263_220_154_597_250),
Staker(0x8633ADAf2438703d6D7f953829A4fe0c95FbeC44, 14_574_784_535_592_207_846),
Staker(0xAD142B79f2500Bf194C174f06C7dC901A2CdA74f, 7_123_937_386_942_958_617),
@@ -315,7 +298,6 @@ contract RestoreRewardsProposal {
Staker(0x16eb5Fbb2a5c7dAbC2c7688482378e89471d5724, 56_528_851_406_540_169_265),
Staker(0x356eE97D7D560af2E97E9f9EEe56b2e09D60e6F5, 2_357_571_123_330_435_682_004),
Staker(0x000AD8F56D3408abE29466189612d1B7B19E4420, 8_944_601_804_979_063_344),
Staker(0xc82ceD242a7c064EC0ef3742BDea830aEB46D614, 225_374_382_403_472_958_564),
Staker(0xAd412239848f37a5dDb8fAbb523D05F4FFdB2651, 1_852_483_360_172_530_551),
Staker(0x21c756E2c7B898BDa8a3b2A77e4C56D855Ab9414, 52_258_855_596_837_389_305),
Staker(0xa6Ba7cddc1c4fBfFBA96eCE341F9baA1c35fA76e, 10_324_733_292_812_452_226),
@@ -350,14 +332,12 @@ contract RestoreRewardsProposal {
Staker(0xA103c48Dbe3E804C23a98C5f159cEb3305c28E7b, 3_039_820_725_899_735_674),
Staker(0xab03945BC97F6899902D4296Ff97cAE8dbdc1A11, 66_797_846_279_254_338_952),
Staker(0xB945e8074C3e2F758B045Cb9a30066EE33CDB87E, 8_960_852_709_660_572_526),
Staker(0xDEB1c51514ee12d9F76Eb67AfCb7B4c33B466449, 8_131_473_545_148_842_396),
Staker(0x00377B2FC0044Dec6507855eDd6531aF1755cCe4, 187_316_100_663_496_504_711),
Staker(0xDaABa4C3a3026149a7a811bcb4B4EE9F23B61800, 1_342_110_570_226_429_076),
Staker(0x10aab4B0EF76AA2AC9b5909e671517a1171B050E, 9_816_488_209_589_379_461),
Staker(0xD9D10dc5609d77F2A15FAa68414835A6ed19269B, 95_363_084_515_727_944_710),
Staker(0x71e989dC58c879D26C2efDce097edeE505A57a28, 2_088_864_348_657_925_026),
Staker(0xdF20a1124d6B44e19ad75675a622d9c9669E59B6, 88_352_293_222_343_728_212),
Staker(0xaA8B1a05dF753F54DE787a752cB9E7808f447820, 23_946_074_798_869_806_567),
Staker(0x7E5c540b343fB854782617dECc82FBc1745b5591, 14_767_739_390_099_031_589),
Staker(0x209D49fda266C0AB257648555f8459F90e154aEd, 129_761_028_103_842_230_426),
Staker(0xF4d2D64D1f9190A9daB0960c80e5C73c04710184, 20_259_718_574_398_138_635),
@@ -386,11 +366,7 @@ contract RestoreRewardsProposal {
Staker(0xea76eE7035aF65410D290cB7E2Ed8Fc01C395266, 6_866_348_488_289_388_870),
Staker(0xC2e6B265cb965DED721566f0f9Eb5ab1A6162A21, 22_971_027_302_959_450_151),
Staker(0x4d6A11EbEC10E133A5007578Ad792F765ED724F2, 1_523_390_814_593_599_013_009),
Staker(0xaF305fEfDc439cb1CA9FAC2f9d271fD2CC7B3F05, 34_558_215_533_487_668_461),
Staker(0x164f9ECFc5Ec74fAC1Ba1ca28E71Fd57FeadCD27, 43_630_581_854_870_958_303),
Staker(0xddbc1841BE23b2ab55501Deb4d6bc39E3f8AA2d7, 57_697_184_564_150_419_473),
Staker(0x7b5edF38D955dd9deC103aF05c2D68B28e02Ad90, 990_145_869_312_977_038_005),
Staker(0xE4143f6377AEcd7193b9731d1C28815b57C4f5Ab, 794_513_313_076_462_735_653),
Staker(0x9Fd4d0dE8A3A8a8F2aC003A5ece295CE9512d9c6, 36_016_585_133_757_988_164),
Staker(0x3390937ec4D4b94002BCacf65D2F98594b4980eF, 6_453_311_584_351_983_424),
Staker(0xA207ac236dFdeE6F885d0Cc1D0C8100b46fA91EE, 1_450_736_948_351_239_615),
@@ -399,12 +375,9 @@ contract RestoreRewardsProposal {
Staker(0xc71cB68d38dF4E2190128DCb7E39bD1e72Fc3A2F, 13_498_777_595_192_377_744),
Staker(0x3E40eCBf8eB74fB708b8cCeA28c1C9312697aFDd, 2_547_293_201_582_353_144),
Staker(0x1e4d844528F3C9890bE6c3de38Dc8c695Cd06B20, 27_853_939_827_678_230_227),
Staker(0x45a4a7b51f8691Bd52988d8ee3f01F7518f6B056, 11_167_199_970_888_954_708),
Staker(0x4BF646757dA7067E683EB20cD122AfFBc0E67e39, 4_512_233_232_588_903_004),
Staker(0xb6242d8F02bA15917A84bD83C2eeee0e45288a03, 9_403_472_182_706_909_584),
Staker(0x6f4CbC2E042ed0D1Df4bf14d00eEb52Ff1E0e5F8, 9_748_334_349_185_074_783),
Staker(0x92374BA66EE27f207F9efff0837FF6D707006304, 58_838_358_111_071_620_908),
Staker(0x6dF07d3864c5F7ee564B5920199374C0b864E7d6, 664_290_901_673_954_681_162),
Staker(0x04700e0Ef1bCD91d36e7CE63FE93d651DFB272cA, 13_074_452_933_044_923_946),
Staker(0x8a1d5F23566c802CccEF7f02d5f216c37c8e44aD, 1_481_488_396_230_202_148),
Staker(0xfa2176D82cbA00d54998E6C37616b75ceCef08a0, 8_723_821_105_751_268_318),
@@ -412,14 +385,13 @@ contract RestoreRewardsProposal {
Staker(0x592340957eBC9e4Afb0E9Af221d06fDDDF789de9, 3_571_261_202_347_432_870),
Staker(0x000000Cd6521Ed1a65FAe0678eA15aF4EEAD74fe, 1_431_414_111_205_873_746),
Staker(0xC49415493eB3Ec64a0F13D8AA5056f1CfC4ce35c, 1_213_791_173_344_605_522),
Staker(0xa6eDC956290b7Ce416c5d8EDc67E1C32506Fe099, 366_757_732_355_918_570_636),
Staker(0xbd0fac9A19E8E19F6245eD20411E22D4786752c8, 4_355_144_205_984_655_655)
];
for (uint64 i = 0; i < stakers.length; i++) {
for (uint64 i = 0; i < stakers.length; i++){
accrueOldReward(stakers[i].addr, stakers[i].oldRewards);
}
IERC20(tornAddress).transfer(stakingProxyAddress, 51_038_101_771_805_874_869_526);
IERC20(tornAddress).transfer(stakingProxyAddress, 42_754_780_712_309_224_285_728);
}
}

View File

@@ -11,4 +11,10 @@ interface ITornadoStakingRewards {
function setReward(address account, uint256 amount) external;
function checkReward(address account) external view returns (uint256);
function accumulatedRewards(address account) external view returns (uint256);
function accumulatedRewardPerTorn() external view returns (uint256);
function addBurnRewards(uint256 amount) external;
}

View File

@@ -2,6 +2,8 @@
pragma solidity ^0.6.12;
pragma experimental ABIEncoderV2;
import { Staker } from "@interfaces/ITornadoStakingRewards.sol";
contract Mock {
// Developer address with staked TORN
address public constant TEST_REAL_ADDRESS_WITH_BALANCE = 0x9Ff3C1Bea9ffB56a78824FE29f457F066257DD58;
@@ -39,4 +41,372 @@ contract Mock {
);
uint16 public constant PERMIT_FUNC_SELECTOR = uint16(0x1901);
uint256 public constant cheatingStakersCount = 357;
uint256 public constant summaryRestoreAmount = 42_754_780_712_309_224_285_728;
function getOldStakers() public pure returns (Staker[cheatingStakersCount] memory) {
Staker[cheatingStakersCount] memory stakers = [
Staker(0xb2C95127308876B0dA00dCE7798412bcA95C9Fee, 261_891_050_760_386_479_981),
Staker(0x52f4B90dF9560E50389107baCCD13e8BC1e5a516, 5_519_577_581_187_935_401),
Staker(0x679959449b608AF08d9419fE66D4e985c7d64D96, 6_634_938_965_540_161_678),
Staker(0xf93d494D5A3791e0Ceccf45DAECd4A5264667E98, 8_490_060_208_866_067_358),
Staker(0xCbc3906EFE25eD7CF06265f6B02e83dB67eF41AC, 319_116_867_023_920_470_808),
Staker(0xe9B4aA5906C6e842e52aE7B7ab4dec3EE52362cB, 39_678_252_992_546_852_551),
Staker(0x875Bf94C16000710f721Cf453B948f23B7394ec2, 13_947_501_300_799_785_176),
Staker(0x642df98E9d71Ba533dF7288512cF63D34a907659, 135_240_431_519_943_709_355),
Staker(0xCa5d2D6758AF981B93a03D17A5A3EC5F80c180EB, 7_721_278_572_113_994_465),
Staker(0x201dD47dadA5165D792e6B4bDC2600e2FC5d7375, 3_376_734_302_476_765_689),
Staker(0x97b90FBc8904F861F76CB06BFa0A465b72C5E662, 85_583_028_288_278_705_143),
Staker(0xd3660816c68EF4DB79D2cCBFA2E6D623dfD65699, 135_764_830_626_382_535_905),
Staker(0x32f8E5d3F4039d1DF89B6A1e544288289A500Fd1, 1_536_360_162_595_381_679),
Staker(0xe2506955723C01dDd6e619dD0829e28F76328c41, 72_958_648_431_519_163_392),
Staker(0x3Df488Bd07C2082E84B1CD63F343Cf3d538342bA, 107_098_359_836_630_121_582),
Staker(0x0b7C43AF43D76f79b6f6CfBAFb3A01ddE0468225, 18_243_581_064_710_552_362),
Staker(0x524b7c9B4cA33ba72445DFd2d6404C81d8D1F2E3, 8_414_647_798_389_006_172),
Staker(0xfDEEc44b6c63E637fA3348092A9F952A02B2E695, 1_468_551_637_230_600_353),
Staker(0x59bb22550fb8b886Bf4c939592f9551cE686d4a3, 16_137_118_612_498_456_595),
Staker(0x429774AdF20a28Cc95D0b3af784934EA79A82c0d, 15_365_126_956_977_699_391),
Staker(0x111C36a714282706208ebBe6E353C1a27e86F047, 7_447_509_943_286_775_069),
Staker(0xF36c9777a2cA739dca10855Ad0F3B7833c889C75, 12_390_989_636_498_390_570),
Staker(0x9fB89686c645fCCEF25Bc1Fb4028Caa8351F1b2b, 8_514_556_973_152_955_213),
Staker(0xB1583e01ACA426807985FAf9438c9a4cEF73B1A7, 2_769_004_780_372_765_071),
Staker(0xcDfb26F93F2D5e0F4b76190e5bC740b3A3DA16F4, 1_986_870_853_342_994_225),
Staker(0xDbcb5D2a6c77F1a8069ff686F88FC552F2F3eFCC, 2_691_179_623_359_894_955),
Staker(0x85f8BeC61f75De3Dbad1bBd4CDD168ea362bDaeA, 118_525_403_763_250_297_030),
Staker(0xA3A89931799Ba449A7bd1658EfD9C8662dd22BcA, 4_471_048_279_368_398_062),
Staker(0xeafA9AA6832c076D5af3d58D9224E218CA074f04, 3_278_339_837_838_322_677),
Staker(0x25713B024a8004727Ba79c43647a77c7447948dB, 16_833_083_830_815_723_474),
Staker(0x73D23cDaBBb25B0E039470ea940514Ca30744277, 6_268_058_376_469_446_863),
Staker(0xB157ba30e3467DdBC844f14F02b4ba741f1d549F, 65_080_791_858_799_563_574),
Staker(0xB6dA1D0cac0CAC8d39125d5213E1623750525ed5, 3_582_972_520_064_518_922),
Staker(0xEBf919b0DAfb9ea4BF324108A142C64A69052D8f, 1_492_116_146_713_012_865_552),
Staker(0x60cA7B20DF5BC24De829430483bE764B5D084d69, 4_018_319_868_681_046_086),
Staker(0xeC621c716fCE687011503fbef8110F0b4B41EA03, 3_963_263_371_773_808_775),
Staker(0x076b499e9191A29Fa9210e497cBd89DABC878B6E, 4_403_836_602_105_176_579),
Staker(0x83c418D2eD6670785330B996b47a18492b61e218, 2_423_008_690_534_464_349_496),
Staker(0xcD37EF9120132F71E23982881e19B68aE3B4E871, 6_094_554_447_886_213_907),
Staker(0xff36EdACcEebADC368ea6CACA13E5f3bBD1b43AC, 1_685_473_922_303_763_108),
Staker(0x312044825EB5CD2C4Bb016a7a86ce32240Af9136, 27_126_619_039_727_679_328),
Staker(0x3035A1bBd824041B07f8Ab2297a71A81E00127c5, 14_756_069_076_031_120_181),
Staker(0xeBD7213b1C3E73e9dE1B997d4720Fd92c0818cfa, 3_613_685_844_231_027_457),
Staker(0x39978cc40e2D1d7E127050bDFFFBB0dFcfaEbAd0, 15_230_501_138_086_179_326),
Staker(0x1d7979F557BA38892f25D3d54Fa6C1D75a4CfA27, 18_055_734_821_037_016_750),
Staker(0x69383889dbb0B45F83B82Aa25b7015cC1bd0ae76, 16_140_846_745_256_388_878),
Staker(0x8DE7824675F8bA6E48286c5ad381D59A0F7DA3b8, 13_934_499_607_748_484_588),
Staker(0x9433ea2C250D84d3fD6398699D48728fa610569A, 109_796_210_858_250_476_424),
Staker(0xF99d1946Bf038a1205d430Ec91401E760e5F8F6F, 8_151_047_628_859_550_523_186),
Staker(0x9897Bc7231492CDf163BB81bFF10A5919a73d132, 3_388_092_111_567_580_393_688),
Staker(0x8953C798a6F54ea8907875c51e5D466DE76A1b26, 797_098_747_089_744_161_355),
Staker(0xf4DcA9B37f09D15f8dF740055cEaA860912efe2C, 2_569_990_661_510_076_867),
Staker(0xAdE9e51C9E23d64E538A7A38656B78aB6Bcc349e, 146_771_928_128_749_080_734),
Staker(0xeE1D1ac27A80De54F0ba92b2E25EBb3418495db2, 2_943_758_390_988_392_723),
Staker(0x6C5C3f27004Cb5d03b094054d0F01d97aC8B0B7b, 459_688_139_562_733_477_821),
Staker(0x027Ca422238C0F53F157a61Ee2df44d425EeADA5, 4_215_557_507_159_743_897),
Staker(0x5F5Fd946645511BFBCBe451B8281e2608a9740E1, 10_894_111_710_611_142_586),
Staker(0x4dBD438a45FC9EA6635a7c1f5F8f2dCEAF565ef4, 156_708_583_792_019_610_376),
Staker(0x0022F267eb8A8463C241e3bd23184e0C7DC783F3, 36_248_441_359_369_997_667),
Staker(0x77265BE7cfB120dEAb6E94f6D0db69bD0D79dd4f, 39_644_548_580_130_019_492),
Staker(0xefe8Aa053Ef0C9F1879911ef1C83Da08AD385164, 21_293_829_512_107_120_469),
Staker(0x1ed8bB37f05D408D4b2829d2D8c72FcC824c68C1, 18_516_124_154_569_693_244),
Staker(0x238926025E84475e3182774df480021470f8F978, 27_658_071_363_963_774_207),
Staker(0x0f481DCa44DAbea940CE60826140C0bBD69bC18D, 21_836_415_326_817_810_491),
Staker(0x0c3a4a0ed70fDB29860760b5ca78B116Fe77DE00, 27_166_858_033_213_470_375),
Staker(0x883d8c8dc7887A47F0B0A5d9300f0b604cb7dc13, 19_824_552_416_365_034_915),
Staker(0x327346e623A4334f7c4034D5a73Ac636d33a31c0, 120_755_019_242_057_866_191),
Staker(0xA0F0287683E820FF4211e67C03cf46a87431f4E1, 1_538_812_389_698_165_791),
Staker(0xeafa6FbaebB26F9d07B42f3Fd8906818CE75026F, 365_052_745_349_270_769_699),
Staker(0x728A62B9dFD33E509aa08b68aBa414EDA4500824, 47_932_484_027_594_295_367),
Staker(0x53380cD390f59965d67bD21C1B07B3071FDd7101, 16_630_425_415_229_667_980),
Staker(0xD544E1c38582deB641Ea64AC663d0589eCbF28A3, 15_640_762_200_398_339_347),
Staker(0xB353cA0D3E70f628FAD61A6095Baf06Ce8CeaD3b, 7_931_344_849_621_524_271),
Staker(0x2D56db2f95Ae61c2396d30ABEa61fc91E506943F, 37_056_830_404_435_202_337),
Staker(0xc7557AfDB4C2EF7E2A5e68ed60B1f8AC41c87459, 32_204_391_506_502_234_540),
Staker(0xedA818ef7f5944680b4BcA06578563D2c7Def261, 19_244_624_351_355_060_472),
Staker(0xD1D03F64C6233Db3fd873B5c33B3E713847A4500, 22_679_541_926_066_486_022),
Staker(0x8441A802EdBfD100a2BAc655Bd144dB9c322B135, 16_940_362_905_695_966_352),
Staker(0x8170bCad3a583A0F394C5607B4EBf4AA718191b4, 15_115_630_690_239_261_804),
Staker(0x4C135B8bC69D9d404673776A7D680465656c0B1D, 18_651_557_745_134_101_778),
Staker(0x34c4D38E784D447bE6C944672bD6D31A9206B015, 11_891_931_505_100_218_503),
Staker(0x96Fb8FC2bcCDaa8298366E0187d950EE9af80dDb, 9_490_287_064_977_661_230),
Staker(0xE9563fcE6Db466C16E733703Dd2D6B1519091BF6, 22_321_586_441_677_961_729),
Staker(0xDDBD9b3068D3EC084a1E226fCB5Dc1378b3EAF32, 4_616_882_688_199_488_374),
Staker(0x43d07807707e752956b58430C92abC0Ccb7d682D, 5_666_719_269_688_485_142),
Staker(0xaB9424c3507BE50d8D9b185e58E1bfF47F1db642, 6_893_674_565_343_587_818),
Staker(0x6FF6D709297875378C8b06721c21f40FE1989e9B, 5_651_699_506_237_154_120),
Staker(0x520A8bAB202e1516964185856eC5176899f06BE4, 22_318_463_746_001_413_626),
Staker(0xd99804992cdb929E07D5015007a0849B900f6f84, 1_714_276_914_913_887_335),
Staker(0x02DB6D137bFd99fcB0167718221555C402C82b39, 29_830_462_422_811_005_139),
Staker(0x3E0ac6febCE010bf7aCf8c73bc7Fe1D1001DF997, 3_229_113_172_124_504_136),
Staker(0x52441E08FC4AcFd088044067BF7612326eaEFccE, 2_017_897_499_173_780_670),
Staker(0x03DA0543aAd12E681f71f17FF9e9B9747A9F077C, 535_039_892_724_559_238_209),
Staker(0x6eA8BfAa4697187D3BB1E27688931d73BcbbEC0b, 96_160_012_179_317_268_085),
Staker(0xc7246dee8EB74a00078a0af0e9e449BeA1Ec12dD, 6_674_277_150_011_094_414),
Staker(0x5Ef47F1B3d81E4F49317505bE9f275ECdbBdeF5b, 4_227_887_050_751_472_989),
Staker(0xB1BfFe6C1f3DE2301A13dE4D661b532474BD3dEC, 8_838_817_614_668_270_933),
Staker(0xE0a9Cf94C4c41a7709B55D9bA37D788A8DF19F9E, 45_499_259_144_753_600_486),
Staker(0x295F43a11127a8ec0227F26591272a4C81CcEC99, 2_513_561_913_094_324_146),
Staker(0x06F166E11d765aE936E7ec36777E1b4B6f0Cb83B, 50_508_975_824_735_610_016),
Staker(0x3034cAaB0eF35C89EB47da2c5f8529238039f3da, 6_175_636_472_097_169_884),
Staker(0x328809A567b87b6123462c3062e8438BBB75c1c5, 27_792_590_979_636_856_692),
Staker(0x066A2EDcC0b7278A2CF5Bf2a040b4a54a41A9550, 15_282_821_843_244_071_780),
Staker(0x1023aE712D5F219e9166a9D286e183226DFAafa6, 42_806_051_433_469_301_743),
Staker(0x5db63f987817910Bbb9656B5210990408d3831fB, 24_809_335_995_263_418_515),
Staker(0x8DcA15154B8b90f452958e9cEd1abD1CE93294F1, 11_136_858_220_905_236_877),
Staker(0x758E5C35ee11F2B22337228f5e8f53ad4006e6BD, 2_546_006_253_314_181_590),
Staker(0x75F3fC9189fd3228a4178e544CdE26b75Da81Bf3, 90_923_808_354_167_295_865),
Staker(0x90e14E059B28Af64B52d4Da0442b22052f507eF1, 280_919_372_012_890_102_042),
Staker(0xdB8Ecd8C4265a9026eEDff388000eC3b43A27bF4, 13_800_470_519_810_267_784),
Staker(0x097DaA98F6dB6a17395bb540eE274bb0f227BF42, 344_296_461_842_409_422_541),
Staker(0xeDE1D96DE24A6DA0371eBfa93E0BB6aBe71c56F0, 20_341_123_034_358_760_717),
Staker(0xBcB9C5e230786Ec2E39e131DD6C6337ABC9F170e, 362_940_257_688_800_318_458),
Staker(0x043AF0101c49bDF8F2174EB5d66F0371520fb609, 20_825_635_245_427_249_690),
Staker(0x92a4F58009dF9eaC5f2AF6d05977683639f0060e, 4_900_663_194_893_379_705),
Staker(0x344651A2445484bd2928eB46D2610DaaC1B42A66, 90_808_834_336_748_165_277),
Staker(0x2490419318b3F69e8dc209604056f40Eb350d0d7, 345_414_794_727_582_170_459),
Staker(0xDE9902F23Cf51e6C29018a708551a57E87FF27C9, 1_995_890_341_186_114_459),
Staker(0x1e5Ac6A2663F1501EeEf5c28b7f49Bb06F2a0951, 20_698_519_319_739_813_584),
Staker(0x4aAE2d5072385b02465263d5feb91bb1995D4f37, 41_435_296_640_491_630_100),
Staker(0x14E7CA16876965f4C0DAeF6b8ce5cAb79D66f264, 12_092_835_555_676_796_148),
Staker(0x0df59978Cc975e27C5E4e19d355e025F0770F088, 72_651_265_399_984_484_867),
Staker(0x0D75Afb0d88CD5633a62C52afc345eFDc4588DF1, 4_350_806_294_721_919_927),
Staker(0x0EC559DFD33272CAB065E9F6cD67A33538c61371, 1_107_177_978_257_047_893),
Staker(0xDe30040413b26d7Aa2B6Fc4761D80eb35Dcf97aD, 25_268_214_259_626_074_238),
Staker(0x85e6C3c83929eE45712EFF4F89c5E74cCddB5D41, 80_916_830_705_010_170_686),
Staker(0xC346A5dc3b3821AEeF3f3fFB70989631521E41cD, 15_156_100_876_567_919_885),
Staker(0x5d17B355538A9ea9b45A0018e11b36947fC16376, 942_457_608_672_105_748_438),
Staker(0xAaF7168Bae99a4860D7729745B22C4b48d1f9Adb, 19_406_970_552_591_675_727),
Staker(0xdD16D1b97527EC781412B63D1f75518c84aEC1A2, 6_847_031_664_606_680_728),
Staker(0xEb076Bbf46c7040ee7CbA3539135CCc43335e1ae, 5_866_771_869_282_653_696),
Staker(0x38caf52451889fced55B7939FE5Db6f930C2A48E, 15_004_591_391_718_163_554),
Staker(0x6A3c302B7CE07F7063C787031BeB00E7eF206621, 2_745_693_129_070_525_796),
Staker(0x48Ef3De608AB2304dBB0c4497d266F3BF5506e7B, 1_346_590_027_777_001_145),
Staker(0x3716905b040D5cd8a7DdE784918199117d72c3B3, 1_400_844_245_925_263_369),
Staker(0xB835b4e277094D4AF9Fbb66e9f5Db9e6E8dC65dB, 25_683_271_096_264_423_274),
Staker(0x42DbF634c256acd17beDDC1330488F1BEa7B8BDf, 319_523_008_529_625_373_272),
Staker(0xE7304bA0f157f2Ade94015934284b6704BC72911, 39_826_654_578_302_448_107),
Staker(0xE06bF8125273Ead3814aBDE0D548079991F5DD8a, 22_645_804_997_633_317_877),
Staker(0xaa9298F0c3e97DdA6277713fd3Ed6e2A389E7260, 3_572_475_984_033_907_702),
Staker(0xC9D32C7e16d71aF1739618356F1e3F2c69e8784a, 2_812_672_628_757_140_199),
Staker(0xCcC24DD1FE711d9f47A42a04b16b789669A21C98, 252_786_587_455_637_451_074),
Staker(0x0091a0aAF911A27133713028a83644224FcD7103, 4_391_483_020_114_108_858),
Staker(0x74E5B46a2A39F86ECc8CABCc409556953A688484, 3_576_335_685_734_120_104),
Staker(0x3eE9378Fb0809a243FcF7C30865941675d766D71, 36_560_597_025_246_678_361),
Staker(0x81348BB6CFA32662cE76aE5FcC8c54F056CE7042, 31_557_802_849_905_329_659),
Staker(0x60B12324fb28132c403Ed26b8677Ca4De31b2e16, 3_727_585_088_600_139_687),
Staker(0x30106D3Ad21e81DDc6ba94965BD8d39c036F2deD, 1_970_108_755_076_228_794),
Staker(0x06981EfbE070996654482F4F20786e0CEf0f8740, 24_910_012_428_663_008_434),
Staker(0x8b9Ea63c9e1efccb66d3B7732dC6528B71C04Be0, 11_585_355_470_389_709_302),
Staker(0xE708a1bAfA472C56CC2C28771935116e3113234D, 6_267_465_513_978_284_340),
Staker(0xaB1b1fe0bf8BD1582156F8FdCaA323b19FB78258, 6_249_903_736_588_606_570),
Staker(0x6CC256173725Da442A250769d3BE58c0dd0C883c, 3_387_498_383_708_101_530),
Staker(0xb827857235d4eACc540A79e9813c80E351F0dC06, 11_871_116_784_644_301_587),
Staker(0x647e9e26DA82C29AAFbbFB1C3f45d916AA9b300d, 4_952_575_083_129_263_084),
Staker(0x4e6428489612D68e8fFe37e93eF147B413229d9D, 2_510_757_099_624_166_329),
Staker(0x26AE281c9fdB974c766fcB0e407A51dE0aB56931, 4_163_814_860_661_655_277),
Staker(0x3764d6708658d817b730755A15b68e0D02829c6B, 2_270_554_981_194_684_000),
Staker(0xFe2beF6AAD7E9Fd68D2C9f5D70DEFf3472F5619B, 2_029_003_869_229_046_450),
Staker(0x8DE5a4DC8746F30DeDB9493DE76A4C187Ed8f987, 1_845_651_550_309_534_566),
Staker(0x31606580b4c52A1181eb9f74c1b9Db302c8e16e8, 18_040_413_854_595_059_909),
Staker(0x5b29348B1Bf4574E0F1e94b700ea9Cff5aC92F40, 10_777_894_208_285_543_318),
Staker(0x545f78a51FD98A6bC1e556341200A51236b6D93C, 2_691_530_089_466_222_755),
Staker(0x92e74E50edCE4573d181C03cA889f72640cD3a94, 136_869_113_432_790_215_052),
Staker(0x3dD44f129563787449367046c9cBF5610f21467f, 65_876_838_873_310_486_868),
Staker(0x3a8A1F045cd4F7246c6B3A78861269CC6065433a, 340_485_819_042_729_840_453),
Staker(0x0A54cf15a8719DB69B5cC40d797a213ca9407B8E, 81_284_025_913_702_862_445),
Staker(0x00831CF531ccb05ff16F6fcBFe4D328AA52514d2, 19_507_081_489_070_834_374),
Staker(0xA838F88fDFCf112Cbe53d748ea881614B3097b92, 17_275_804_796_657_260_322),
Staker(0x95880f2E70203f759168665Feb6948E81Fe5dF77, 97_122_566_594_954_315_364),
Staker(0x593ce184bcEe0940330A850Af23c7cA89A02324A, 3_206_450_110_568_998_389),
Staker(0x0050faCd2C04930257438b213FE9E132a26E5a29, 39_500_678_847_473_273_923),
Staker(0x1d14080067dE02E048DdE58a936b4EBED7ee56e4, 10_668_566_291_321_367_858),
Staker(0x15626a85DeA2d02B251661a9235219aE6c74ed65, 1_253_582_576_072_733_139),
Staker(0xd43f3716CbB9386352880a9BD52f7F07aC01752B, 15_806_302_538_242_973_172),
Staker(0xbb6d1648A8BeF51603Badd347Dc91eb7D04a43e5, 23_298_218_841_136_959_317),
Staker(0xD7b2879C8922cd704E41E8CC1f18f6994D6B7C36, 366_822_563_020_873_062_384),
Staker(0x7a628E9bCC082844797C37c79084ed6BC99e6Abc, 5_827_905_211_411_400_869),
Staker(0x438c89F4Af0C0913b0cB547d4AC58a2ac42Cd406, 1_286_158_784_632_769_851),
Staker(0x64aCfC01b898031Bc3D3542Fd774F949f1B3A3eD, 22_629_791_720_280_120_817),
Staker(0xDaa5C5a5B6725666B1e37B14dc8e1FCB446c5952, 38_342_813_347_447_445_646),
Staker(0x5dab475E601D55efa2290D27333913e025C7Bd89, 47_271_335_991_155_105_027),
Staker(0x6a62Fa571a02f6B7Ac8d36709517418ba80dCd65, 13_295_284_932_273_869_168),
Staker(0x4051e1fcD4Be1366a0CDcfA47ca717868A96575E, 116_686_435_879_133_319_146),
Staker(0xC2a92a640d148eee15d16AC307fE8039E37B9073, 29_926_470_058_225_692_109),
Staker(0xDc2b529C3AF6DF66956c2224cA7c55806fc07B27, 16_067_505_175_313_969_066),
Staker(0xB3AAd889bf41Ec39571aFa78aa5D9A26a05DDaAb, 66_039_342_561_078_583_726),
Staker(0xe5FaEE1719c058FF3452ad875C78b17a22881266, 4_372_707_248_071_008_517),
Staker(0x4303Ddc9943D862f2B205aF468a4A786c5137E76, 38_062_310_707_197_965_348),
Staker(0xa1eBC8bdE2F1F87fe24F384497b6bD9cE3B14345, 136_274_007_743_711_470_585),
Staker(0xaf095d9cedBc20c8Bb0A75ED9509c1f31DC4E7E6, 929_679_243_081_448_689_081),
Staker(0x4839460F05b2a8fC1b615e0523EbC46eFba75420, 33_126_482_078_138_485_018),
Staker(0x093Fc1387349F65d6382F36dfcb209509B8213f3, 9_450_092_762_258_946_997),
Staker(0x3E6Dd7771f2819136f17f8EeBD6616CAD09Ed012, 31_488_252_123_340_309_847),
Staker(0x6b69c30354Cef94ee9d77DBC7BD268B4A6683825, 67_307_670_852_095_513_804),
Staker(0xc8d51E5a9293426d678400f05fDF8395fFE34187, 1_159_086_427_507_011_821),
Staker(0x1CE7DC66CC98c61A573105514d073D64a9a8608f, 26_389_224_886_673_669_669),
Staker(0xD3069f6050A3dd4ECCc27b6A66E5C401aB59DeD5, 1_131_703_913_861_582_424_146),
Staker(0xc6DFfE2C1C910A3E049b29638bE0286645054f3C, 29_472_347_834_775_340_843),
Staker(0x2753dEeD6Fc665ff159c94aEAFb8a19E4525831E, 25_294_315_679_682_630_786),
Staker(0x0d4E989c7620C8749c9417d2BF218896C767B606, 3_364_398_457_228_954_809_190),
Staker(0x4aDD4bC3B1E9075E37C7FF6728Fe67716244F44C, 1_329_614_003_989_061_149),
Staker(0x4963C9C61f48272969587c27aA4e6384798d48cA, 146_304_190_741_347_394_112),
Staker(0x6fb4becf05497b79F0fCF61CfA5075efAA137DDF, 24_433_501_822_630_023_422),
Staker(0x6f9BB7e454f5B3eb2310343f0E99269dC2BB8A1d, 7_311_696_825_863_967_912),
Staker(0xb4e39F6D3d386E98AF0C064E087aCBC9A8F08944, 31_036_510_205_773_583_247),
Staker(0x2462375371935c8122895e701380A06CE815B0FD, 45_031_939_040_278_717_234),
Staker(0x24f04EC62597C11752c47448228B63052ED3158a, 90_815_074_343_246_091_464),
Staker(0xA11109126af2c5904fdc5b6203108Fef5770E85E, 17_491_569_071_641_631_106),
Staker(0x8904FFC6Aa039dB5941De11309a42372F3F7D2FD, 89_018_897_961_346_317_265),
Staker(0xa729adDeFe1fa7BCe87053ed55D55EDdDD13De60, 21_709_183_619_942_034_343),
Staker(0x409ac9C16B2CD569EC06bb9eceF97eeFDe0e8054, 15_006_870_038_073_374_755),
Staker(0xdF3c8E63677C79b24608bDed80CeD65667513BcB, 541_718_227_741_233_200_336),
Staker(0xF7CA6e80753b7ef2647D1B391efbbfefaD03a25C, 19_295_606_810_439_445_963),
Staker(0x9265f86d58b348060E43216f968bda8A6Bb63572, 98_620_127_775_202_999_418),
Staker(0xCfbd27a6F88184Ff7F3C2cBC79a673Cd440f3f8c, 5_924_335_043_678_903_077),
Staker(0xcE1fFD4cfE424757D6e597293566195Fba6f4cD8, 110_373_688_594_429_476_293),
Staker(0x08e65423a1553e1e952737777Fa1739bD48AD6Ce, 16_803_855_495_656_227_235),
Staker(0xA4882E304906DA516fCf9851AA87d6BA251755Ed, 1_953_120_388_485_130_071),
Staker(0x2E63Dbd91657dc5fa97213Ba6a1AEb5f194805F6, 251_251_776_059_847_254_774),
Staker(0xe509bd972346DB660D29f811F9302A065C10D545, 28_817_656_632_797_696_252),
Staker(0x68d1C68E033A0594737255953abFd511bEEd7A8f, 1_030_951_197_409_454_477),
Staker(0x4273397532A8dF43a6607C4441e3EB6edF63acf3, 31_104_820_080_384_860_799),
Staker(0x378FdAa857d5E1340eBCc9975326A41ECe2c9B4B, 14_112_288_396_935_461_682),
Staker(0x4672a4dD8390b712d555739066749Cf087ce03B5, 3_888_614_225_495_013_923),
Staker(0xf32b28572000130714a36d33531aE621a30aDd8f, 9_027_844_878_265_729_121),
Staker(0xA556a5a50d2C786617263414878214A9159d1433, 16_276_470_593_499_298_613),
Staker(0x12168AEa666Be756E1aD0595fEd9C306442a4103, 36_412_749_452_500_453_957),
Staker(0xE70eF2B9A263855535727Ee014C6Ffaf01881Ae3, 35_128_546_559_175_901_644),
Staker(0x96499F1DAF16C20736B15345B3bC961027aBf9A9, 3_132_594_551_228_880_028),
Staker(0x2b153c4F0648A1fBF74387b30B2364793e5B78F2, 11_840_570_785_343_594_608),
Staker(0x7803Ab56769dDa5432CDbd63749a6BEeb3180008, 67_349_370_537_699_327_633),
Staker(0x4F50d47D20380172746527bbeAa274940C38EFAC, 109_134_986_268_076_670_848),
Staker(0x237cfe337CD641d3a45C8A2ed3540D9b4De5e1f8, 16_924_961_748_013_267_657),
Staker(0x89bFD67276dfEFeDCdc39f186024AeC773C9deb1, 16_206_266_280_488_707_844),
Staker(0x05a4448597935c508e4ad0D2CF56d56beDb246Ce, 5_564_985_557_053_713_810),
Staker(0xFeAe121618049802Ccb40f094536a7B186642699, 26_051_172_063_635_311_610),
Staker(0x069Dd24FC8ABEC3708841a4726617c17BC74d5eC, 28_952_332_778_826_791_728),
Staker(0x11A2A99396c1BC4D878c9ac86401d38d5f2f4caE, 61_198_275_715_198_687_233),
Staker(0x26D3b88d464A575784Be70Edc5F9290dC5e296DB, 143_520_553_783_208_184_300),
Staker(0x4ffc1A4bD191935C603df061065Ce97C25C70687, 1_104_677_208_403_973_125),
Staker(0x7Abbdbd51813d85B448F887b946719Dd2B09D6F7, 28_496_157_399_564_678_982),
Staker(0x3C7ddEB357e4341A18cfC587343a4463a280B9c5, 15_766_263_220_154_597_250),
Staker(0x8633ADAf2438703d6D7f953829A4fe0c95FbeC44, 14_574_784_535_592_207_846),
Staker(0xAD142B79f2500Bf194C174f06C7dC901A2CdA74f, 7_123_937_386_942_958_617),
Staker(0x4fFDAeB9f4ec23254B6DFA41eEeF2C8d23f8c554, 33_194_297_731_999_668_131),
Staker(0x47789dFc4a68726eaE0eB930D91f4a6bEeC8b1Eb, 3_487_926_054_013_619_640),
Staker(0xf5626231B3C6A75Ec68858A4Ef43Cdb7Afb3e642, 17_275_370_664_752_538_996),
Staker(0x369ae1DC8978Fd4D7C73eD322454019db999343F, 1_528_376_231_901_983_047),
Staker(0xb03384cA294C06E8d04B08412E8467ff2363E5E3, 211_578_919_069_650_342_377),
Staker(0xD483C2bDae0d41EF8f1A3A0B1B0f7f123aab4bA9, 16_797_954_501_761_561_253),
Staker(0x68eCbC648655Ba1aA045B2f50A219190dE97f9FD, 20_547_718_671_359_444_564),
Staker(0x528db62f1828b284EB2041296aecb4dAC9F0515c, 4_165_181_895_662_237_060),
Staker(0x6A3738c6299f45c31697aceA647D49EdCC9C28A4, 97_760_260_576_325_925_251),
Staker(0xBF224728D032054a7c293eD9BBf94F4Ce06E3C5d, 7_449_726_293_008_071_375),
Staker(0xc74d1af789F5A0223448Db69a1B56c84845e17d5, 86_279_890_580_822_470_582),
Staker(0x5a8345CA0017EAc8A6b699f00e77b6a66bc671D3, 2_677_176_111_126_764_125),
Staker(0x26D5060620F39Cd8011bDa8b883488239444fDa4, 1_516_607_929_338_102_731),
Staker(0xDf90418385aF4E9833603069DEaF7C71d76f83a2, 155_357_572_254_018_554_532),
Staker(0x8B11c69BfC02fE187543e87611207b253Ca62081, 141_988_817_509_681_621_914),
Staker(0x6147E468231f2Df9fa370d45EddddE9010B765cC, 83_415_353_831_892_079_722),
Staker(0xA1F12899eE593a41cd0D640706CE3feAfcCbA845, 1_005_970_156_314_423_558),
Staker(0x851a7e50F5BE154D3596276a44cA013cD4E5C3Ee, 3_874_585_207_860_333_623),
Staker(0x38dD8aF98907064f1Eea0540b3aB4da56DB28497, 5_642_347_071_859_268_579),
Staker(0xa212F0fDD9e6cacfa6fEC8Bf56207eA344C66afD, 2_212_922_409_934_864_847),
Staker(0x7305303A1511Ecd0583bAc2031D878E36B3c7fD3, 2_246_547_675_850_021_513),
Staker(0x16eb5Fbb2a5c7dAbC2c7688482378e89471d5724, 56_528_851_406_540_169_265),
Staker(0x356eE97D7D560af2E97E9f9EEe56b2e09D60e6F5, 2_357_571_123_330_435_682_004),
Staker(0x000AD8F56D3408abE29466189612d1B7B19E4420, 8_944_601_804_979_063_344),
Staker(0xAd412239848f37a5dDb8fAbb523D05F4FFdB2651, 1_852_483_360_172_530_551),
Staker(0x21c756E2c7B898BDa8a3b2A77e4C56D855Ab9414, 52_258_855_596_837_389_305),
Staker(0xa6Ba7cddc1c4fBfFBA96eCE341F9baA1c35fA76e, 10_324_733_292_812_452_226),
Staker(0xd90825b15f70B64f81BaB600F7F56Fe3F86747CE, 3_354_805_705_660_717_938),
Staker(0xFB96D60ce3ee83ed4BC71c6E0da10C537601b77C, 22_611_440_234_158_131_327),
Staker(0x6D6f1D15EBb0215B3613e99C4daFd5E1b9F5cC96, 14_791_730_194_629_501_463),
Staker(0xb1Bf7F11E408463CC8F449F2433ccCe8945aa04b, 17_864_069_861_611_643_481),
Staker(0xeb0fCD59212E521918b514c64313eF5a3dd101f8, 3_901_271_037_084_752_091),
Staker(0xaDACa82Bc5aCdc51f9439306CE853E23D9804095, 229_610_218_449_354_480_332),
Staker(0x34DF0B83cf4F30683f8AB2Ac971a52A5f663FEb4, 22_958_042_522_429_606_777),
Staker(0x16525102F287C20B4C432548E553576F1C4694E8, 1_560_109_119_830_653_830),
Staker(0x9901bbcFfb45fA06d7D3fc17858599b2EBfA7F98, 4_647_859_755_961_887_347),
Staker(0xF2Ba32f180B243D3138DEd0E1F1BdbdcCBCE0702, 5_519_983_644_068_960_970),
Staker(0x7b22Fb198DceF415763c13661509Fd369Ef8B198, 15_252_516_305_505_956_415),
Staker(0x3654EcfC4e406c8320DCE4Af95C318369488f6b6, 35_867_894_048_125_994_013),
Staker(0xC380D86E375E0b4de213332a22eFb5943cfbcd26, 33_029_862_300_700_755_690),
Staker(0xC2Bd458e3F08282D2195611Aa37dE9C2e93E02cC, 7_474_008_907_661_241_347),
Staker(0x9C258268d067ed41C7E6e6042671CE416713FBDE, 1_173_569_337_143_956_794),
Staker(0xFB75781F96B2B589a1d40C659c3b3C522b5D4876, 37_132_672_019_373_242_644),
Staker(0x17B728b8B47952306671848d3beb799F1fb44A91, 2_661_115_072_540_344_958),
Staker(0xbC063735a5b8bdd12611157E7E0F29D1570D892D, 105_476_579_411_544_400_855),
Staker(0x4E54A86bBeD09e75F3466E79A81BCDD0341a7C3F, 1_059_258_680_340_063_793),
Staker(0x0839aE5F7E675f8a9ac4afDBE0723116986e55b4, 3_875_490_507_064_413_906),
Staker(0xe7c724F87EcFf8E2f563962f96b6c291cBD729cF, 51_733_651_718_901_275_551),
Staker(0x1fe7d323946A7C3B644528baA42eFf13056cd2B4, 73_872_062_802_036_390_199),
Staker(0x32Af25467b00aAe516505B3331cfEc52092ea5BA, 2_162_614_748_223_216_488),
Staker(0x0eCD341cbcB8Ae2b6f61d497242e4Ad51b64183b, 5_145_936_718_002_554_228),
Staker(0x48c0477Bf79a59e505d26eB33c5b331502a511B2, 49_085_362_121_291_012_983),
Staker(0xE5A5BfC1772D4A2b44Add05aae63026A89486C1B, 20_972_207_440_915_443_277),
Staker(0x27f6809603f051F227aD4B3C547825F5Ae1F8616, 3_800_217_976_471_907_423),
Staker(0xc66f327Ef28f47ce41245F7F42Be5796DdAA45Fa, 15_846_925_154_344_478_196),
Staker(0xA103c48Dbe3E804C23a98C5f159cEb3305c28E7b, 3_039_820_725_899_735_674),
Staker(0xab03945BC97F6899902D4296Ff97cAE8dbdc1A11, 66_797_846_279_254_338_952),
Staker(0xB945e8074C3e2F758B045Cb9a30066EE33CDB87E, 8_960_852_709_660_572_526),
Staker(0x00377B2FC0044Dec6507855eDd6531aF1755cCe4, 187_316_100_663_496_504_711),
Staker(0xDaABa4C3a3026149a7a811bcb4B4EE9F23B61800, 1_342_110_570_226_429_076),
Staker(0x10aab4B0EF76AA2AC9b5909e671517a1171B050E, 9_816_488_209_589_379_461),
Staker(0xD9D10dc5609d77F2A15FAa68414835A6ed19269B, 95_363_084_515_727_944_710),
Staker(0x71e989dC58c879D26C2efDce097edeE505A57a28, 2_088_864_348_657_925_026),
Staker(0xdF20a1124d6B44e19ad75675a622d9c9669E59B6, 88_352_293_222_343_728_212),
Staker(0x7E5c540b343fB854782617dECc82FBc1745b5591, 14_767_739_390_099_031_589),
Staker(0x209D49fda266C0AB257648555f8459F90e154aEd, 129_761_028_103_842_230_426),
Staker(0xF4d2D64D1f9190A9daB0960c80e5C73c04710184, 20_259_718_574_398_138_635),
Staker(0xc4313fCdCC95e1352c8E9892EACC43f3C0302241, 9_114_984_026_955_066_440),
Staker(0xf68de31d7fC80A70959966F9Aa78e86A7b418A10, 6_793_910_531_583_492_359),
Staker(0x27358dcAfE169293640ABcd5a50B2156e3CA7D0b, 1_396_572_756_872_979_834),
Staker(0x47B9cCa44fe405D12ff56aaCd1Df6dbA4A79Ae28, 116_401_415_234_644_535_634),
Staker(0xefb3141fF2CC4BAcC32274560F67Ce44A02b47a2, 2_695_994_774_470_615_737),
Staker(0xc0466d5E152d97fE028CDAF761Dddd578637a494, 7_703_236_971_827_668_108),
Staker(0x213A8b4A4719D7C74377Bb2a582e7Aa1c5d4d6e4, 1_906_251_511_229_877_016),
Staker(0x4ce41B12e79Aba3A0B16D1A6826c5687085A8e68, 12_376_605_768_375_176_829),
Staker(0x71917F124be5C0Cd97aDBE7AB472f4C82577B542, 19_387_564_291_842_605_250),
Staker(0x2a2a1FB6382a528F1B23E76d3Ed6F4C17A9e5966, 78_211_613_640_632_999_853),
Staker(0x0BecabF81208CCF08b320334Ee26f65fB28B7B7C, 19_706_556_422_398_085_618),
Staker(0x343F48B346b0cE11342ffdEDaDAC4135E1FD525a, 52_474_802_671_702_736_494),
Staker(0x408BD39659242CC87abCC578c76f41f730CF67d6, 5_361_177_370_238_939_271),
Staker(0x15c15B2a88406f6434e0902639B7B353458e5498, 7_280_010_872_916_183_974),
Staker(0x1E7f4bA9ECc1F74467851dA248693bd0f66B657A, 2_268_046_082_115_219_840),
Staker(0x0F46576F3b8b0ed6522e4b200Df53ac73251b911, 43_106_930_066_979_612_507),
Staker(0xaAaC34d30d6938787c653AAfB922bc20bFa9C512, 56_033_971_131_839_936_055),
Staker(0xDE092c055E3a8486Fa2441A5685448D4851C2DBa, 5_089_562_467_001_778_052),
Staker(0x4e1083f454cAE424c8C1165D4f8e0Ef5e462cBa7, 10_821_472_545_808_036_648),
Staker(0x758aB8aC42a8c44dF8C31129Db146c65c2669391, 91_872_937_975_269_665_468),
Staker(0xb3a7FBC2fa38C18ad4433aE93FE7F215Fd2D057f, 2_143_380_905_682_922_209),
Staker(0x149da2CB603A8818Fb2d703D72D46390Cd09A6D9, 33_141_454_797_818_273_137),
Staker(0xea76eE7035aF65410D290cB7E2Ed8Fc01C395266, 6_866_348_488_289_388_870),
Staker(0xC2e6B265cb965DED721566f0f9Eb5ab1A6162A21, 22_971_027_302_959_450_151),
Staker(0x4d6A11EbEC10E133A5007578Ad792F765ED724F2, 1_523_390_814_593_599_013_009),
Staker(0x7b5edF38D955dd9deC103aF05c2D68B28e02Ad90, 990_145_869_312_977_038_005),
Staker(0x9Fd4d0dE8A3A8a8F2aC003A5ece295CE9512d9c6, 36_016_585_133_757_988_164),
Staker(0x3390937ec4D4b94002BCacf65D2F98594b4980eF, 6_453_311_584_351_983_424),
Staker(0xA207ac236dFdeE6F885d0Cc1D0C8100b46fA91EE, 1_450_736_948_351_239_615),
Staker(0xa39fE8D3094e2D69Bd579Dc2bc2fc44Feb54Fc57, 451_325_359_651_864_296_017),
Staker(0xc8E68D674Df0Eab152926C4F0EE7D0ac0745c715, 37_874_059_988_948_844_769),
Staker(0xc71cB68d38dF4E2190128DCb7E39bD1e72Fc3A2F, 13_498_777_595_192_377_744),
Staker(0x3E40eCBf8eB74fB708b8cCeA28c1C9312697aFDd, 2_547_293_201_582_353_144),
Staker(0x1e4d844528F3C9890bE6c3de38Dc8c695Cd06B20, 27_853_939_827_678_230_227),
Staker(0x4BF646757dA7067E683EB20cD122AfFBc0E67e39, 4_512_233_232_588_903_004),
Staker(0xb6242d8F02bA15917A84bD83C2eeee0e45288a03, 9_403_472_182_706_909_584),
Staker(0x92374BA66EE27f207F9efff0837FF6D707006304, 58_838_358_111_071_620_908),
Staker(0x04700e0Ef1bCD91d36e7CE63FE93d651DFB272cA, 13_074_452_933_044_923_946),
Staker(0x8a1d5F23566c802CccEF7f02d5f216c37c8e44aD, 1_481_488_396_230_202_148),
Staker(0xfa2176D82cbA00d54998E6C37616b75ceCef08a0, 8_723_821_105_751_268_318),
Staker(0xE4fB69507Cfa7d0654E392E6C1e401918123a85a, 6_672_203_296_221_673_628),
Staker(0x592340957eBC9e4Afb0E9Af221d06fDDDF789de9, 3_571_261_202_347_432_870),
Staker(0x000000Cd6521Ed1a65FAe0678eA15aF4EEAD74fe, 1_431_414_111_205_873_746),
Staker(0xC49415493eB3Ec64a0F13D8AA5056f1CfC4ce35c, 1_213_791_173_344_605_522),
Staker(0xbd0fac9A19E8E19F6245eD20411E22D4786752c8, 4_355_144_205_984_655_655)
];
return stakers;
}
}

View File

@@ -21,6 +21,7 @@ contract MockProposal is Test, ProposalUtils {
new TornadoStakingRewards(_governanceAddress, _tokenAddress, _relayerRegistryAddress);
RestoreRewardsProposal proposal = new RestoreRewardsProposal(address(governanceStakingImplementation));
proposeAndExecute(address(proposal));
}
}

View File

@@ -4,15 +4,189 @@ pragma solidity ^0.6.12;
pragma experimental ABIEncoderV2;
import { MockProposal } from "./MockProposal.sol";
import { TornadoStakingRewards } from "@root/TornadoStakingRewards.sol";
import { Staker, ITornadoStakingRewards } from "@interfaces/ITornadoStakingRewards.sol";
import { Test } from "@forge-std/Test.sol";
import "@forge-std/console2.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract TestProposal is MockProposal {
function test() public executeCurrentProposalBefore {
TornadoStakingRewards staking = TornadoStakingRewards(_stakingAddress);
ITornadoStakingRewards staking = ITornadoStakingRewards(_stakingAddress);
console2.log("Developer rewards: %s TORN", staking.checkReward(TEST_REAL_ADDRESS_WITH_BALANCE));
function testGovernanceBalance() public {
IERC20 TORN = IERC20(_tokenAddress);
uint256 governanceBalanceBeforeExecution = TORN.balanceOf(_governanceAddress);
console2.log("Governance balance before proposal execution: %s TORN", governanceBalanceBeforeExecution / _tornDecimals);
createAndExecuteProposal();
uint256 governanceBalanceAfterExecution = TORN.balanceOf(_governanceAddress);
console2.log("Governance balance after proposal execution: %s TORN", governanceBalanceAfterExecution / _tornDecimals);
uint256 governanceBalanceDifference = governanceBalanceBeforeExecution - governanceBalanceAfterExecution;
console2.log("Governance balance difference: %s TORN, %s", governanceBalanceDifference / _tornDecimals, governanceBalanceDifference);
require(governanceBalanceDifference == summaryRestoreAmount, "Incorrect Governance balance after execution");
}
function testOtherUsersRewardUnchanged() public {
uint256 rewardsBeforeProposal = staking.checkReward(TEST_REAL_ADDRESS_WITH_BALANCE);
console2.log("Developer rewards before proposal execution: %s TORN", rewardsBeforeProposal / _tornDecimals);
createAndExecuteProposal();
uint256 rewardsAfterProposal = staking.checkReward(TEST_REAL_ADDRESS_WITH_BALANCE);
console2.log("Developer rewards after proposal execution: %s TORN", rewardsBeforeProposal / _tornDecimals);
require(rewardsAfterProposal == rewardsBeforeProposal, "Other stakers rewards changed");
}
function testCannotCallSetRewardsNotFromGovernance() public executeCurrentProposalBefore {
// Trying to set rewards to myself, expect error revert call
vm.startPrank(TEST_ADDRESS_ONE);
vm.expectRevert(bytes("only governance"));
staking.setReward(TEST_ADDRESS_ONE, 100_000 ether);
vm.stopPrank();
require(staking.checkReward(TEST_ADDRESS_ONE) == 0, "Rewards accrued without permissions (not from Governance call)");
vm.startPrank(_governanceAddress);
staking.setReward(TEST_ADDRESS_ONE, 100_000 ether);
vm.stopPrank();
require(staking.checkReward(TEST_ADDRESS_ONE) == 100_000 ether, "Rewards not accrued by Governance");
}
function getStakersRewardsSum(Staker[cheatingStakersCount] memory stakers) internal returns (uint256) {
uint256 rewardsSum = 0;
for (uint16 i = 0; i < stakers.length; i++) {
rewardsSum += staking.accumulatedRewards(stakers[i].addr);
}
return rewardsSum;
}
function testVerifyStakersAccrual() internal {
Staker[cheatingStakersCount] memory stakers = getOldStakers();
uint256[cheatingStakersCount] memory rewardsBefore;
uint256[cheatingStakersCount] memory rewardsAfter;
for (uint16 i = 0; i < stakers.length; i++) {
rewardsBefore[i] = staking.accumulatedRewards(stakers[i].addr);
}
createAndExecuteProposal();
for (uint16 i = 0; i < stakers.length; i++) {
rewardsAfter[i] = staking.accumulatedRewards(stakers[i].addr);
}
for (uint16 i = 0; i < stakers.length; i++) {
console2.log("\nStaker address: %s", stakers[i].addr);
console2.log("Rewards before: %s", rewardsBefore[i]);
console2.log("Rewards after: %s", rewardsAfter[i]);
console2.log("Real difference: %s", (rewardsAfter[i] - rewardsBefore[i]));
console2.log("Expected difference: %s", stakers[i].oldRewards);
require(rewardsAfter[i] - rewardsBefore[i] == stakers[i].oldRewards);
}
}
function testStakingContractReplenishedCorrect() public {
Staker[cheatingStakersCount] memory stakers = getOldStakers();
uint256 stakersRewardsSumBeforeExecution = getStakersRewardsSum(stakers);
console2.log("Old stakers rewards sum before proposal execution: %s TORN", stakersRewardsSumBeforeExecution / _tornDecimals);
uint256 stakingContractBalanceBeforeExecution = IERC20(_tokenAddress).balanceOf(_stakingAddress);
console2.log("Staking contract balance before proposal execution: %s TORN", stakingContractBalanceBeforeExecution / _tornDecimals);
createAndExecuteProposal();
uint256 stakersRewardsSumAfterExecution = getStakersRewardsSum(stakers);
console2.log("\nOld stakers rewards sum after proposal exectuion: %s TORN", stakersRewardsSumAfterExecution / _tornDecimals);
uint256 stakingContractBalanceAfterExecution = IERC20(_tokenAddress).balanceOf(_stakingAddress);
console2.log("Staking contract balance after proposal execution: %s TORN", stakingContractBalanceAfterExecution / _tornDecimals);
uint256 stakersRewardSumDifference = stakersRewardsSumAfterExecution - stakersRewardsSumBeforeExecution;
uint256 stakingContractBalanceDifference = stakingContractBalanceAfterExecution - stakingContractBalanceBeforeExecution;
console2.log("\nStaking contract replenish amount: %s TORN", stakingContractBalanceDifference / _tornDecimals);
console2.log("Stakers restored rewards sum: %s TORN", stakersRewardSumDifference / _tornDecimals);
require(
stakersRewardSumDifference == stakingContractBalanceDifference,
"Staking replenish sum doesn't match with stakers restored rewards sum"
);
}
function testAccumulatedRewardPerTornNotChanged() public {
uint256 accumulatedRewardsPerTornBeforeExecution = staking.accumulatedRewardPerTorn();
console2.log("Accumulated reward per 1 TORN before proposal execution: %s", accumulatedRewardsPerTornBeforeExecution / _tornMaximumSupply);
createAndExecuteProposal();
uint256 accumulatedRewardsPerTornAfterExecution = staking.accumulatedRewardPerTorn();
console2.log("Accumulated reward per 1 TORN after proposal execution: %s", accumulatedRewardsPerTornAfterExecution / _tornMaximumSupply);
require(accumulatedRewardsPerTornBeforeExecution == accumulatedRewardsPerTornAfterExecution, "Accumulater reward per TORN changed");
}
function testRewardAccrualsMechanismCorrect() public executeCurrentProposalBefore {
IERC20 TORN = IERC20(_tokenAddress);
uint256 toBurn = 10_000 ether;
retrieveAndLockBalance(TEST_STAKER_PRIVATE_KEY, TEST_STAKER_ADDRESS, PROPOSAL_THRESHOLD);
uint256 stakerLockedBalance = governance.lockedBalance(TEST_STAKER_ADDRESS);
require(stakerLockedBalance == PROPOSAL_THRESHOLD, "Invalid test staker locked balance");
uint256 stakerRewardsBeforeBurning = staking.checkReward(TEST_STAKER_ADDRESS);
console2.log("Staking rewards before burning: %s TORN", stakerRewardsBeforeBurning / _tornDecimals);
burnTokens(_governanceAddress, toBurn, staking);
uint256 stakerRewardsAfterBurning = staking.checkReward(TEST_STAKER_ADDRESS);
console2.log(
"Staking rewards after burning 10 000 TORN: %s TORN\n", stakerRewardsAfterBurning / _tornDecimals
);
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(governance.userVault());
uint256 receivedReward = stakerRewardsAfterBurning - stakerRewardsBeforeBurning;
uint256 expectedRewards = stakerLockedBalance * toBurn / governanceLockedAmount;
console2.log("Expected staking rewards: %s TORN", expectedRewards / _tornDecimals);
console2.log("Staker received rewards: %s TORN\n", receivedReward / _tornDecimals);
require(receivedReward == expectedRewards, "Expected and received rewards don't match");
}
function testAccumulatedRewardCanBeUpdated() public executeCurrentProposalBefore {
uint256 accumulatedRewardPerTornBeforeBurning =
staking.accumulatedRewardPerTorn() / _tornMaximumSupply;
console2.log(
"Accumulated reward per TORN right after proposal execution: %s TORN",
accumulatedRewardPerTornBeforeBurning / _tornDecimals
);
burnTokens(_governanceAddress, 10_000_000 ether, staking);
uint256 accumulatedRewardPerTornAfterBurning = staking.accumulatedRewardPerTorn() / _tornMaximumSupply;
console2.log(
"Accumulated reward per TORN after burning 10 000 000 TORN: ~ %s TORN",
accumulatedRewardPerTornAfterBurning / _tornDecimals
);
require(
accumulatedRewardPerTornAfterBurning > accumulatedRewardPerTornBeforeBurning,
"Staking rewards isn't updated"
);
}
}

View File

@@ -5,6 +5,8 @@ pragma experimental ABIEncoderV2;
import { Utils } from "./Utils.sol";
import { Proposal, IGovernance } from "./interfaces/IGovernance.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract ProposalUtils is Utils {
IGovernance internal governance = IGovernance(payable(_governanceAddress));
@@ -29,8 +31,7 @@ contract ProposalUtils is Utils {
}
function proposeAndVote(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);
retrieveAndLockBalance(TEST_PRIVATE_KEY_ONE, TEST_ADDRESS_ONE, PROPOSAL_THRESHOLD + 1 ether);
/* ----------PROPOSER------------ */
vm.startPrank(TEST_ADDRESS_ONE);
@@ -45,12 +46,6 @@ contract ProposalUtils is Utils {
vm.stopPrank();
/* ------------------------------ */
/* -------------VOTER-------------*/
vm.startPrank(TEST_ADDRESS_TWO);
governance.castVote(proposalId, true);
vm.stopPrank();
/* ------------------------------ */
return proposalId;
}
@@ -59,5 +54,23 @@ contract ProposalUtils is Utils {
waitUntilExecutable(proposalId);
IGovernance(_governanceAddress).execute(proposalId);
returnTokensToGovernanceAfterVoting(proposalId);
}
function returnTokensToGovernanceAfterVoting(uint256 proposalId) public {
uint256 retrievedAmount = PROPOSAL_THRESHOLD + 1 ether;
uint256 proposalExecutableTime = getProposalExecutableTime(proposalId);
uint256 tokensUnlockTime = proposalExecutableTime + 4 days + 1 seconds;
if(block.timestamp < tokensUnlockTime) vm.warp(tokensUnlockTime);
vm.startPrank(TEST_ADDRESS_ONE);
governance.unlock(retrievedAmount);
IERC20(_tokenAddress).transfer(_governanceAddress, retrievedAmount);
vm.stopPrank();
}
}

View File

@@ -7,6 +7,7 @@ import { ERC20Permit } from "torn-token/contracts/ERC20Permit.sol";
import { Test } from "@forge-std/Test.sol";
import { Parameters } from "@proprietary/Parameters.sol";
import { ITornadoStakingRewards } from "@interfaces/ITornadoStakingRewards.sol";
import { Mock } from "./Mock.sol";
import { IGovernance } from "./interfaces/IGovernance.sol";
@@ -37,4 +38,10 @@ contract Utils is Parameters, Mock, Test {
vm.stopPrank();
/* ----------------------------*/
}
function burnTokens(address caller, uint256 amount, ITornadoStakingRewards staking) internal {
vm.startPrank(caller);
staking.addBurnRewards(amount);
vm.stopPrank();
}
}

View File

@@ -41,4 +41,6 @@ interface IGovernance {
function unlock(uint256 amount) external;
function execute(uint256 proposalId) external payable;
function userVault() external view returns (address);
}

View File

@@ -0,0 +1,21 @@
import fs from "fs";
import path from "path";
import { getStakersLockedBalancesSum } from "../utils/stakers";
import { currentProposalVotingStartBlock } from "../utils/config";
async function main() {
const stakersLockedBalanceSum = await getStakersLockedBalancesSum(currentProposalVotingStartBlock);
console.log("Locked balance of stakers to who we want restore rewards:", stakersLockedBalanceSum.div(1e18).toFixed(2), "TORN");
fs.writeFileSync(
path.join("data", "stakersLockedBalanceSum.txt"),
`Locked balance of stakers to who we want restore rewards: ${stakersLockedBalanceSum.toString(10)} (~ ${stakersLockedBalanceSum
.div(1e18)
.toFixed(2)} TORN)`,
{ encoding: "utf-8" }
);
}
main();

View File

@@ -1,5 +1,8 @@
export const governanceAddress = "0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce";
export const oldStakingAddress = "0x2FC93484614a34f26F7970CBB94615bA109BB4bf";
export const multicallContractAddress = "0xeefBa1e63905eF1D7ACbA5a8513c70307C1cE441";
export const currentProposalVotingStartBlock = 17492630;
export const governanceDeployedBlock = 11474695;
export const governanceRewardsProposalBlock = 14173399;
export const hackBlock = 17299139;
export const hackBlock = 17299139;

View File

@@ -1,20 +1,21 @@
import Web3 from "web3";
import BigNumber from "bignumber.js"
import { AbiItem } from 'web3-utils';
import BigNumber from "bignumber.js";
import { AbiItem } from "web3-utils";
import { EthAddress, IStaker } from "./@types/staker";
import * as dotenv from "dotenv";
import { governanceAddress, governanceRewardsProposalBlock, hackBlock, oldStakingAddress } from "./config";
import { governanceAddress, governanceRewardsProposalBlock, hackBlock, oldStakingAddress, multicallContractAddress } from "./config";
import GovernanceAbi from "../abi/GovernanceAbi.json";
import StakingAbi from "../abi/StakingABI.json";
import MulticallABI from "../abi/MultiCallABI.json";
dotenv.config();
const web3 = new Web3(process.env.MAINNET_RPC_URL as string);
function getGovernanceFunctionSelector(functionName: string): string {
const lockFunctionAbi = GovernanceAbi.find(item => item.name == functionName);
const lockFunctionAbi = GovernanceAbi.find((item) => item.name == functionName);
if (!lockFunctionAbi) throw new Error(`Cannot find function ${functionName} in Governance contract ABI`);
const selector = web3.eth.abi.encodeFunctionSignature(lockFunctionAbi as AbiItem);
@@ -28,10 +29,11 @@ async function getAddressesStakersWithProssibleRewards(): Promise<Array<EthAddre
/* Don't need to fetch all "lock" or "lockAndApproval" transactions from Governance contract,
* because user rewards start updating only when RewardUpdateSuccessful events is emitted.
*/
const rewardsUpdateEvents =
await governanceContract.getPastEvents("RewardUpdateSuccessful", { fromBlock: governanceRewardsProposalBlock });
const rewardsUpdateEvents = await governanceContract.getPastEvents("RewardUpdateSuccessful", {
fromBlock: governanceRewardsProposalBlock,
});
const governanceStakers = rewardsUpdateEvents.map(event => event.returnValues.account as string);
const governanceStakers = rewardsUpdateEvents.map((event) => event.returnValues.account as string);
return [...new Set(governanceStakers)];
}
@@ -40,14 +42,59 @@ export async function getStakersWithRewardsBeforeHack(): Promise<Array<IStaker>>
const stakingContract = new web3.eth.Contract(StakingAbi as AbiItem[], oldStakingAddress);
const stakersAddresses = await getAddressesStakersWithProssibleRewards();
let stakersWithRewardsBeforeHack: Array<IStaker> = [];
for (const address of stakersAddresses) {
// Check stakers rewards on previous block before hack
const rewardsBeforeHack = await stakingContract.methods.checkReward(address).call({}, hackBlock - 1);
// Discard stakers with rewards less than 1 TORN, because accruing each reward requires paying gas
if (BigNumber(rewardsBeforeHack).div(1e18).isGreaterThan(1))
stakersWithRewardsBeforeHack.push({ address, rewardBalance: BigNumber(rewardsBeforeHack) });
}
const multiCallQuery: Array<[string, object]> = stakersAddresses.map((stakerAddress) =>
stakingContract.methods.checkReward(stakerAddress).encodeABI()
);
const stakersWithRewardsBeforeHackRawData = await useMultiCall(oldStakingAddress, multiCallQuery, hackBlock - 1);
const stakersWithRewardsBeforeHack: Array<IStaker> = stakersWithRewardsBeforeHackRawData.map((reward, index) => ({
address: stakersAddresses[index],
rewardBalance: BigNumber(reward),
}));
return stakersWithRewardsBeforeHack;
// let stakersWithRewardsBeforeHack: Array<IStaker> = [];
// for (const address of stakersAddresses) {
// // Check stakers rewards on previous block before hack
// const rewardsBeforeHack = await stakingContract.methods.checkReward(address).call({}, hackBlock - 1);
// // Discard stakers with rewards less than 1 TORN, because accruing each reward requires paying gas
// if (BigNumber(rewardsBeforeHack).div(1e18).isGreaterThan(1))
// stakersWithRewardsBeforeHack.push({ address, rewardBalance: BigNumber(rewardsBeforeHack) });
// }
return stakersWithRewardsBeforeHack.filter((staker) => staker.rewardBalance.div(1e18).isGreaterThan(1));
}
export async function getStakersWithdrawedAfterHack(): Promise<Array<EthAddress>> {
const stakingContract = new web3.eth.Contract(StakingAbi as AbiItem[], oldStakingAddress);
const withdrawRewardEvents = await stakingContract.getPastEvents("RewardsClaimed", { fromBlock: hackBlock });
const stakersWithdrawedAfterHack = withdrawRewardEvents.map((event) => event.returnValues.account as string);
return stakersWithdrawedAfterHack;
}
async function useMultiCall(contractAddress: EthAddress, queryArray: Array<Object>, callBlock?: number): Promise<any[]> {
const multiCallContract = new web3.eth.Contract(MulticallABI as AbiItem[], multicallContractAddress);
const multicallQueryArray = queryArray.map((query) => [contractAddress, query]);
const { returnData } = await multiCallContract.methods.aggregate(multicallQueryArray).call({}, callBlock);
return returnData;
}
export async function getStakersLockedBalancesSum(block: number): Promise<BigNumber> {
const governanceContract = new web3.eth.Contract(GovernanceAbi as AbiItem[], governanceAddress);
// All stakers who had more than 1 TORN in rewards at the time of the hack
const stakersWithRewardsBeforeHack = await getStakersWithRewardsBeforeHack();
// Stakers who withdrew rewards from the time of hack until the balance of the old Staking contract was nullified
const stakersWithdrawedAfterHack = await getStakersWithdrawedAfterHack();
// It makes no sense to restore awards to those who already withdrew them from the old Staking contract
const stakersToRestoreRewards = stakersWithRewardsBeforeHack.filter((staker) => !stakersWithdrawedAfterHack.includes(staker.address));
const lockedBalances: Array<string> = await useMultiCall(
governanceAddress,
stakersToRestoreRewards.map((staker) => governanceContract.methods.lockedBalance(staker.address).encodeABI()),
block
);
return lockedBalances.reduce((acc, cur) => acc.plus(BigNumber(cur)), BigNumber(0));
}