Platform: Code4rena
Start Date: 28/10/2021
Pot Size: $30,000 ETH
Total HM: 8
Participants: 19
Period: 3 days
Judge: leastwood
Total Solo HM: 4
Id: 47
League: ETH
Rank: 14/19
Findings: 3
Award: $408.50
🌟 Selected for report: 0
🚀 Solo Findings: 0
382.0579 USDC - $382.06
loop
The price of pricePerShare
in WrappedIbbtcEth.sol is dependant on two things:
pricePerShare
of core
.updatePricePerShare
being invoked every X time to update the pricePerShare
of wibBTC.The only time updatePricePerShare
is invoked inside the contract is during the initialize function, all other instances have to be an external call. When invoking updatePricePerShare
the lastPricePerShareUpdate
value is set to the current time, which is likely to insure the price stays up-to-date. Currently the contract does not check whether the price is up-to-date or whether it has been updated recently. Meanwhile, balanceOf
, totalSupply
, balanceToShares
and sharesToBalance
depend on pricePerShare
being up-to-date. While it's not a direct issue for these functions specifically considering they are restricted to view
, both transfer
and transferFrom
use balanceToShares
and are thus indirectly dependent on pricePerShare
. Since value is being transferred in these functions it would be good to ensure the pricePerShare
is up-to-date before completing the transfer.
If I understand it correctly, an arbitrage like this might be possible:
pricePerShare
for both Ibbtc and wIbbtc.pricePerShare
for Ibbtc is lower than wIbbtc, mint wIbbtc using Ibbtc as collateral.updatePricePerShare
in WrappedIbbtcEth to update lastPricePerShare
to the new lower value.balanceToShares
.I may be wrong here due to limited understanding of Curve pools, but I reckon either transfer
or transferFrom
will be used to swap wIbbtc, both of which use balanceToShares
to calculate the amount that will actually be sent.
updatePricePerShare
:
https://github.com/code-423n4/2021-10-badgerdao/blob/main/contracts/WrappedIbbtcEth.sol#L72-L77
transfer
/transferFrom
relevant parts:
balanceToShares
:
https://github.com/code-423n4/2021-10-badgerdao/blob/main/contracts/WrappedIbbtcEth.sol#L155-L157
Add a require statement for transfer
and transferFrom
to ensure pricePerShare
is updated either using something like require(block.timestamp > lastPricePerShare + x)
with x as the chosen time interval or require(pricePerShare == core.pricePerShare())
.
#0 - 0xleastwood
2021-12-04T09:30:30Z
Same affected area as #86
26.436 USDC - $26.44
loop
The following functions are declared as public, but can be limited to external:
initialize
:
transfer
:transferFrom
:#0 - 0xleastwood
2021-12-04T05:07:07Z
Duplicate of #3