⚔️Steal from the Truster

The learning process will be more beneficial for you if you will avoid the hints.

However, if you are frustrated, open these by order of frustration:

Hint 1

The code is very short, read the flashLoan function code, especially the following line:

target.functionCall(data);

See that the contract uses two user/attacker-controller parameters here - target and data.

Hint 2

Carefully read up the call flow of the functionCall to see what it actually does.

Start by following the @openzeppelin/contracts/utils/Address.sol import until you find this function:

function functionCallWithValue(
    address target,
    bytes memory data,
    uint256 value,
    string memory errorMessage
) internal returns(bytes memory) {
    require(address(this).balance >= value, "Address: insufficient balance for call");
    require(isContract(target), "Address: call to non-contract");

    (bool success, bytes memory returndata) = target.call{ value: value } (data);
    return verifyCallResult(success, returndata, errorMessage);
}

Note how it eventually triggers target.call.

It means we can execute any call we want, on behalf of the TrusterLenderPool.sol contract.

Hint 3

Since we can basically run code in behalf of the target contract, we can use ERC20's approve method to allow our user to spend tokens.

In the test's file solution section, try to fill in the redacted part of this snippet with ERC's approve method call, approving your user to spend tokens.

let interface = new ethers.utils.Interface([".."])
let data = interface.encodeFunctionData("approve", [player.address, TOKENS_IN_POOL]);

After that, call the contract's flashLoan to invoke the approval, and attempt to transfer funds from the pool to your user.

Last updated