Open code423n4 opened 3 years ago
Really like this exploit idea. Currently this is possible since the Trader is not whitelisted (eg there is no whitelisted relayer address). With this added, this exploit is no longer possible as only off chain relayers can place orders with the trader.
Disagree with the severity mainly due to the fact that executing this exploit once would only cause insurance funding to not be paid for a single hour. For insurance funding to never be paid, you would have to time this transaction as the first transaction on each and every hour. This would quickly be noticed. The only affect on this would be insurance depositors miss interest payments for a few periods.
Marking this as medium risk as a front-runner could keep doing this for not paying any funding using a bot.
Handle
gpersoon
Vulnerability details
Impact
It's possible to avoid paying insurance in the following way:
The insurance rates are 0 now and no-one pays insurance. The gas costs relative to the insurance costs + the flash loan fees determine if this is an economically viable attack. Otherwise it is still a grief attack This will probably be detected pretty soon because the insurance pool will stay empty. However its difficult to prevent.
Proof of Concept
// https://github.com/code-423n4/2021-06-tracer/blob/main/src/contracts/Insurance.sol#L45 function deposit(uint256 amount) external override {
// https://github.com/code-423n4/2021-06-tracer/blob/main/src/contracts/Insurance.sol#L74 function withdraw(uint256 amount) external override {
// https://github.com/code-423n4/2021-06-tracer/blob/main/src/contracts/Pricing.sol#L69
function recordTrade(uint256 tradePrice) external override onlyTracer { .. if (startLastHour <= block.timestamp - 1 hours) { .. updateFundingRate();
// https://github.com/code-423n4/2021-06-tracer/blob/main/src/contracts/Pricing.sol#L141 function updateFundingRate() internal { .. int256 iPoolFundingRate = insurance.getPoolFundingRate().toInt256(); .. int256 iPoolFundingRateValue = currentInsuranceFundingRateValue + iPoolFundingRate; .. setInsuranceFundingRate(iPoolFundingRate, iPoolFundingRateValue);
// https://github.com/code-423n4/2021-06-tracer/blob/main/src/contracts/Insurance.sol#L204 function getPoolFundingRate() external view override returns (uint256) { .. // If the pool is above the target, we don't pay the insurance funding rate if (poolTarget <= poolHoldings) { return 0; }
Tools Used
Recommended Mitigation Steps
Set a timelock on withdrawing insurance