Add proposal and tests solidity code
This commit is contained in:
parent
8c97665093
commit
51a0b178bf
@ -1,4 +1,4 @@
|
||||
# Proposal title
|
||||
# Proposal to compensate relayer attack losses
|
||||
|
||||
### Changes / effect description
|
||||
|
||||
@ -10,15 +10,14 @@
|
||||
|
||||
- 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))
|
||||
- Node 18 or higher ([Windows](https://github.com/coreybutler/nvm-windows), [Linux](https://github.com/nvm-sh/nvm))
|
||||
|
||||
### Installation
|
||||
|
||||
```text
|
||||
git clone --recurse-submodules <proposal-repo-link>
|
||||
cd <proposal-name>
|
||||
git clone --recurse-submodules https://git.tornado.ws/Theo/proposal-33-compensate-relayer-losses
|
||||
cd proposal-33-compensate-relayer-losses
|
||||
npm install
|
||||
npm run init
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
1
lib/forge-std
Submodule
1
lib/forge-std
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit f73c73d2018eb6a111f35e4dae7b4f27401e9421
|
@ -19,6 +19,7 @@
|
||||
"@openzeppelin/upgrades-core": "^1.26.2",
|
||||
"axios": "^1.5.1",
|
||||
"dotenv": "^16.3.1",
|
||||
"env-cmd": "^10.1.0",
|
||||
"web3": "^4.2.0",
|
||||
"web3-utils": "^4.0.7"
|
||||
},
|
||||
|
@ -15,11 +15,7 @@ async function fetchFailedWithdrawals() {
|
||||
|
||||
let failedWithdrawalTransactions = [];
|
||||
for (let blockNumber = attackStartBlock; blockNumber <= attackEndBlock; blockNumber++) {
|
||||
let block = null;
|
||||
while (block == null)
|
||||
try {
|
||||
block = await web3.eth.getBlock(blockNumber);
|
||||
} catch (e) {}
|
||||
const block = await web3.eth.getBlock(blockNumber);
|
||||
const results = await Promise.allSettled(block.transactions.map((tx) => web3.eth.getTransactionReceipt(tx as string)));
|
||||
const transactions = results.filter((r) => r.status === "fulfilled").map((r) => (r as PromiseFulfilledResult<TxReceipt>).value);
|
||||
failedWithdrawalTransactions.push(...transactions.filter((tx) => tx.to === routerAddress.toLowerCase() && tx.status == 0));
|
||||
|
@ -1,11 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import { IGovernance } from "@interfaces/IGovernance.sol";
|
||||
|
||||
contract ExampleProposal {
|
||||
function executeProposal() public {
|
||||
/* ... */
|
||||
}
|
||||
}
|
29
src/RelayerCompensationProposal.sol
Normal file
29
src/RelayerCompensationProposal.sol
Normal file
@ -0,0 +1,29 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import { IGovernance } from "@interfaces/IGovernance.sol";
|
||||
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
|
||||
contract RelayerCompensationProposal {
|
||||
IERC20 public constant TORN = IERC20(0x77777FeDdddFfC19Ff86DB637967013e6C6A116C);
|
||||
|
||||
struct RelayerLoss {
|
||||
address relayer;
|
||||
uint256 lostAmountInTorn;
|
||||
}
|
||||
|
||||
function executeProposal() public {
|
||||
// Data from 'data/relayerLosses.txt', generated by 'scripts/calculateLosses.ts'
|
||||
RelayerLoss[4] memory relayerLosses = [
|
||||
RelayerLoss(0x864DF9CD806D58341f13602103Bf853066ff962a, 625_894_225_496_155_734_516),
|
||||
RelayerLoss(0x5555555731006f71f121144534Ca7C8799F66AA3, 43_970_301_082_908_267_318),
|
||||
RelayerLoss(0x2Ee39Ff05643bC7cc9ed31B71e142429044A425C, 189_640_345_451_160_934_437),
|
||||
RelayerLoss(0x03392600086874456E08D2bAc104380BCdEBCfC0, 129_757_783_603_193_410_350)
|
||||
];
|
||||
|
||||
for (uint256 i = 0; i < relayerLosses.length; i++) {
|
||||
TORN.transfer(relayerLosses[i].relayer, relayerLosses[i].lostAmountInTorn);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import { ProposalUtils } from "./utils/ProposalUtils.sol";
|
||||
import { ExampleProposal } from "@root/ExampleProposal.sol";
|
||||
|
||||
import { console2 } from "@forge-std/console2.sol";
|
||||
|
||||
contract TestExampleProposal is ProposalUtils {
|
||||
modifier executeCurrentProposalBefore() {
|
||||
createAndExecuteProposal();
|
||||
_;
|
||||
}
|
||||
|
||||
function createAndExecuteProposal() public {
|
||||
address proposalAddress = address(new ExampleProposal()); /* your proposal initialization */
|
||||
|
||||
proposeAndExecute(proposalAddress);
|
||||
}
|
||||
|
||||
/* your tests */
|
||||
|
||||
function testProposal() public executeCurrentProposalBefore { }
|
||||
}
|
56
test/RelayerCompensationProposal.t.sol
Normal file
56
test/RelayerCompensationProposal.t.sol
Normal file
@ -0,0 +1,56 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import { ProposalUtils } from "./utils/ProposalUtils.sol";
|
||||
import { RelayerCompensationProposal } from "@root/RelayerCompensationProposal.sol";
|
||||
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
|
||||
import { console2 } from "@forge-std/console2.sol";
|
||||
|
||||
contract TestExampleProposal is ProposalUtils, RelayerCompensationProposal {
|
||||
modifier executeCurrentProposalBefore() {
|
||||
createAndExecuteProposal();
|
||||
_;
|
||||
}
|
||||
|
||||
function createAndExecuteProposal() public {
|
||||
address proposalAddress = address(new RelayerCompensationProposal());
|
||||
|
||||
proposeAndExecute(proposalAddress);
|
||||
}
|
||||
|
||||
function getRelayerLosses() internal pure returns (RelayerLoss[4] memory) {
|
||||
return [
|
||||
RelayerLoss(0x864DF9CD806D58341f13602103Bf853066ff962a, 625_894_225_496_155_734_516),
|
||||
RelayerLoss(0x5555555731006f71f121144534Ca7C8799F66AA3, 43_970_301_082_908_267_318),
|
||||
RelayerLoss(0x2Ee39Ff05643bC7cc9ed31B71e142429044A425C, 189_640_345_451_160_934_437),
|
||||
RelayerLoss(0x03392600086874456E08D2bAc104380BCdEBCfC0, 129_757_783_603_193_410_350)
|
||||
];
|
||||
}
|
||||
|
||||
function testRelayerGotCompensation() public {
|
||||
RelayerLoss[4] memory relayerLosses = getRelayerLosses();
|
||||
|
||||
uint256[4] memory balancesBeforeProposal;
|
||||
for (uint256 i = 0; i < relayerLosses.length; i++) {
|
||||
balancesBeforeProposal[i] = TORN.balanceOf(relayerLosses[i].relayer);
|
||||
}
|
||||
|
||||
createAndExecuteProposal();
|
||||
|
||||
for (uint256 i = 0; i < relayerLosses.length; i++) {
|
||||
uint256 updatedBalance = TORN.balanceOf(relayerLosses[i].relayer);
|
||||
require(balancesBeforeProposal[i] + relayerLosses[i].lostAmountInTorn == updatedBalance, "Compensation failed");
|
||||
}
|
||||
}
|
||||
|
||||
function testLossesDataIsValid() public pure {
|
||||
RelayerLoss[4] memory relayerLosses = getRelayerLosses();
|
||||
uint256 tornDecimals = 1e18;
|
||||
|
||||
require(relayerLosses[0].lostAmountInTorn / tornDecimals == 625);
|
||||
require(relayerLosses[1].lostAmountInTorn / tornDecimals == 43);
|
||||
require(relayerLosses[2].lostAmountInTorn / tornDecimals == 189);
|
||||
require(relayerLosses[3].lostAmountInTorn / tornDecimals == 129);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user