Skip to content

Commit

Permalink
test: evil router test security limit volatile
Browse files Browse the repository at this point in the history
  • Loading branch information
reednaa committed Nov 22, 2023
1 parent 668d8e1 commit 7753bd5
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 2 deletions.
3 changes: 2 additions & 1 deletion evm/test/CatalystVault/1Volatile/VolatileOneVault.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ import { TestCompareDepositWithWithdraw } from "../Deposit/DepositWithdrawCompar
import { TestSelfSwap } from "../SelfSwap.t.sol";
import { TestSetWeights } from "./SetWeights.t.sol";
import { TestVaultConnections } from "../VaultConnections.t.sol";
import { TestEvilRouterExploitVolatile } from "../non-exploits/EvilRoutor.Securitylimit.Volatile.t.sol";
import {Token} from "../../mocks/token.sol";

contract TestVolatileInvariant is TestInvariant, TestLocalswap, TestCrossChainInterfaceOnly, TestLocalswapMinout, TestPoolTokenInterface, TestSetup, TestSetupFinish, TestSetVaultFee, TestSetGovernanceFee, TestSetWeights, TestLocalswapFees, TestSwapWorthlessTokenLocal, TestEscrow, TestWithdrawInvariant, TestWithdrawComparison, TestCompareDepositWithWithdraw, TestSelfSwap, TestVaultConnections {
contract TestVolatileInvariant is TestInvariant, TestLocalswap, TestCrossChainInterfaceOnly, TestLocalswapMinout, TestPoolTokenInterface, TestSetup, TestSetupFinish, TestSetVaultFee, TestSetGovernanceFee, TestSetWeights, TestLocalswapFees, TestSwapWorthlessTokenLocal, TestEscrow, TestWithdrawInvariant, TestWithdrawComparison, TestCompareDepositWithWithdraw, TestSelfSwap, TestVaultConnections, TestEvilRouterExploitVolatile {

address[] _vaults;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,91 @@ abstract contract TestEvilRouterExploitVolatile is TestCommon, AVaultInterfaces
GARP.processPacket(_metadata, readyMessage, bytes32(abi.encode(address(this))));

// The vault package should revert, thus nothing should be extracted.
assertEq(Token(target_token).balanceOf(toAccount) * 10000001/10000000, 0, "Security limit not working.");
assertEq(Token(target_token).balanceOf(toAccount), 0, "Security limit not working.");

vm.revertTo(snapshot);
}
}

function test_extract_value_via_liquidity_swap() external {
address toAccount = makeAddr("toAccount");
address[] memory vaults = getTestConfig();
setUpChains(DESTINATION_IDENTIFIER);

for (uint256 i = 0; i < vaults.length; ++i) {
uint256 snapshot = vm.snapshot();
address vault = vaults[i];
// set connection between the vault and itself
ICatalystV1Vault(vault).setConnection(
DESTINATION_IDENTIFIER,
convertEVMTo65(vault),
true
);

uint256 target_token_index = 0;
address target_token = ICatalystV1Vault(vault)._tokenIndexing(target_token_index);

uint256 initial_target_token_balance = Token(target_token).balanceOf(vault);

// Get the maximum allowed capacity.
uint256 units = ICatalystV1Vault(vault).getUnitCapacity();

bytes memory fake_payload = constructSendLiquidity(vault, vault, toAccount, units);

fake_payload = addGARPContext(keccak256(fake_payload), address(CCI), address(CCI), fake_payload);

fake_payload = addMockContext(fake_payload);

// Sign the fake payload
(bytes memory _metadata, bytes memory readyMessage) = getVerifiedMessage(address(GARP), fake_payload);

// Execute the fake payload
GARP.processPacket(_metadata, readyMessage, bytes32(abi.encode(address(this))));

assertGt(Token(vault).balanceOf(toAccount) * 10000001/10000000, Token(vault).totalSupply() / 2, "Less than expected exploited, even with margin");
assertLt(Token(vault).balanceOf(toAccount) * 9999999/10000000, Token(vault).totalSupply() / 2, "More than expected exploited, even with margin");

vm.revertTo(snapshot);
}
}

function test_error_extract_too_much_via_liquidity_swap() external {
address toAccount = makeAddr("toAccount");
address[] memory vaults = getTestConfig();
setUpChains(DESTINATION_IDENTIFIER);

for (uint256 i = 0; i < vaults.length; ++i) {
uint256 snapshot = vm.snapshot();
address vault = vaults[i];
// set connection between the vault and itself
ICatalystV1Vault(vault).setConnection(
DESTINATION_IDENTIFIER,
convertEVMTo65(vault),
true
);

uint256 target_token_index = 0;
address target_token = ICatalystV1Vault(vault)._tokenIndexing(target_token_index);

uint256 initial_target_token_balance = Token(target_token).balanceOf(vault);

// Get the maximum allowed capacity.
uint256 units = ICatalystV1Vault(vault).getUnitCapacity() + 1;

bytes memory fake_payload = constructSendLiquidity(vault, vault, toAccount, units);

fake_payload = addGARPContext(keccak256(fake_payload), address(CCI), address(CCI), fake_payload);

fake_payload = addMockContext(fake_payload);

// Sign the fake payload
(bytes memory _metadata, bytes memory readyMessage) = getVerifiedMessage(address(GARP), fake_payload);

// Execute the fake payload
GARP.processPacket(_metadata, readyMessage, bytes32(abi.encode(address(this))));

// The vault package should revert, thus nothing should be extracted.
assertEq(Token(vault).balanceOf(toAccount), 0, "Security limit not working.");

vm.revertTo(snapshot);
}
Expand Down
37 changes: 37 additions & 0 deletions evm/test/TestCommon.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,43 @@ contract TestCommon is Test, Bytes65, IMessageEscrowStructs, TestTokenFunctions,
message = constructSendAsset(sourceVault, destinationVault, toAccount, units, toAssetIndex, 0, 0, address(0), uint32(block.number), uint16(0), hex"");
}

function constructSendLiquidity(address sourceVault, address destinationVault, address toAccount, uint256 units, uint256[2] memory minOuts, uint256 fromAmount, uint32 blocknumber, uint16 underwriteIncentiveX16, bytes memory cdata) pure internal returns(bytes memory message) {
message = abi.encodePacked(
CTX1_LIQUIDITY_SWAP,
abi.encodePacked(
uint8(20),
bytes32(0),
abi.encode(sourceVault)
),
abi.encodePacked(
uint8(20),
bytes32(0),
abi.encode(destinationVault)
),
abi.encodePacked(
uint8(20),
bytes32(0),
abi.encode(toAccount)
),
units,
minOuts[0],
minOuts[1],
fromAmount,
uint32(blocknumber),
uint16(cdata.length),
cdata
);
}

function constructSendLiquidity(address sourceVault, address destinationVault, address toAccount, uint256 units, uint256[2] memory minOuts, uint256 fromAmount) view internal returns(bytes memory message) {
message = constructSendLiquidity(sourceVault, destinationVault, toAccount, units, minOuts, fromAmount, uint32(block.number), uint16(0), hex"");
}

function constructSendLiquidity(address sourceVault, address destinationVault, address toAccount, uint256 units) view internal returns(bytes memory message) {
uint256[2] memory minOuts = [uint256(0), uint256(0)];
message = constructSendLiquidity(sourceVault, destinationVault, toAccount, units, minOuts, 0, uint32(block.number), uint16(0), hex"");
}

function addGARPContext(bytes32 messageIdentifier, address fromApplication, address destinationAddress, bytes memory message) internal returns(bytes memory package) {
return abi.encodePacked(
bytes1(0x00),
Expand Down

0 comments on commit 7753bd5

Please sign in to comment.