// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import "forge-std/Test.sol";
import "../../src/PoC.sol";
import "../interfaces/ISpokeToken.sol";
import "../interfaces/ISpokeCommon.sol";
import "../interfaces/IHubPool.sol";
import "../interfaces/IHub.sol";
import "../interfaces/IBridgeRouter.sol";
import "../interfaces/ILoanManager.sol";
import "../Messages.sol";
import "./AttackContract.sol";
contract InvalidReturnAdapterId is PoC {
ISpokeToken public spokeCircleToken = ISpokeToken(0x89df7db4af48Ec7A84DE09F755ade9AF1940420b);
ISpokeToken public spokeGasToken = ISpokeToken(0xBFf8b4e5f92eDD0A5f72b4b0E23cCa2Cc476ce2a);
ISpokeCommon public spokeCommon = ISpokeCommon(0x6628cE08b54e9C8358bE94f716D93AdDcca45b00);
IHubPool public hubCirclePool = IHubPool(0x1968237f3a7D256D08BcAb212D7ae28fEda72c34);
IHub public hub = IHub(0xaE4C62510F4d930a5C8796dbfB8C4Bc7b9B62140);
ILoanManager public loanManager = ILoanManager(0x2cAa1315bd676FbecABFC3195000c642f503f1C9);
IBridgeRouter public bridgeRouter = IBridgeRouter(0xa9491a1f4f058832e5742b76eE3f1F1fD7bb6837);
IERC20 public constant USDC = IERC20(0x5425890298aed601595a70AB815c96711a31Bc65);
address public user = 0xF745b439965c66425958159e91E7e04224Fed29D;
address public attacker = 0x7039BC43b78A7135F82567C1f973BfAa30F5b8Ab;
IERC20[] private _tokens;
AttackContract private attackContract;
uint256 private ONE_USDC = 10 ** 6;
bytes32 private refAccountId = bytes32("");
bytes32 private userAccountId = bytes32("user");
bytes32 private attackerAccountId = bytes32("attacker");
bytes32 private userLoanId = bytes32("userLoan");
bytes32 private attackerLoanId = bytes32("attackerLoan");
bytes32 private constant RETURN_VALUE = keccak256("ERC3156FlashBorrower.onFlashLoan");
Messages.MessageParams private params;
function setUp() virtual public {
vm.createSelectFork("avalanche_fuji", 34900000);
_tokens.push(USDC);
console.log("\n>>> Initial conditions");
}
function testInvalidReturnAdapterId() public snapshot(user, _tokens) {
vm.startPrank(user);
params = Messages.MessageParams({
adapterId: 1,
returnAdapterId: 2, // invalid return adapter id
receiverValue: 0,
gasLimit: 0,
returnGasLimit: 0
});
spokeCommon.createAccount(params, userAccountId, refAccountId);
spokeCommon.createLoan(params, userAccountId, userLoanId, 2, "userLoan");
uint256 depositAmount = 1_000_000 * ONE_USDC;
USDC.approve(address(spokeCircleToken), depositAmount);
bytes32 invalidAccountId = bytes32("invalidAccountId");
spokeCircleToken.deposit(params, invalidAccountId, userLoanId, depositAmount);
// this tx is reverted from the Hub.receiveMessage() because of the invalidAccountId
// and the messageId is "0x9065bc4c42939ccc651aae9cd013c79763f62723c8d6cd903fcdc3f743e56e78"
// use valid account id to reverse the message
bytes memory extraArgs = abi.encode(userAccountId);
bytes32 messageId = 0x9065bc4c42939ccc651aae9cd013c79763f62723c8d6cd903fcdc3f743e56e78;
bridgeRouter.reverseMessage(1, messageId, extraArgs);
// it is failed and the user's token locked in hubPool forever.
vm.stopPrank();
}
}