Closed lbertenasco closed 3 years ago
I've updated the exploit test to use Uniswap v2 WETH/DAI pool as a hacker, since it has the highest DAI balance. In such configuration is was able to drain the vault in 13 iterations:
1 vault: 204,794,149.30 yCRV (+0.00)
1 hacker: 174,385,544.27 yCRV (+0.00)
2 vault: 199,986,681.61 yCRV (-4,807,467.69)
2 hacker: 178,297,046.90 yCRV (+3,911,502.63)
3 vault: 180,974,697.88 yCRV (-23,819,451.42)
3 hacker: 196,322,485.48 yCRV (+21,936,941.21)
4 vault: 158,594,370.28 yCRV (-46,199,779.03)
4 hacker: 217,609,299.02 yCRV (+43,223,754.75)
5 vault: 132,336,285.05 yCRV (-72,457,864.25)
5 hacker: 242,648,047.32 yCRV (+68,262,503.05)
6 vault: 102,062,444.74 yCRV (-102,731,704.56)
6 hacker: 271,557,278.20 yCRV (+97,171,733.93)
7 vault: 68,799,926.99 yCRV (-135,994,222.31)
7 hacker: 303,295,696.97 yCRV (+128,910,152.70)
8 vault: 36,242,577.46 yCRV (-168,551,571.84)
8 hacker: 334,173,781.26 yCRV (+159,788,236.99)
9 vault: 11,768,677.47 yCRV (-193,025,471.84)
9 hacker: 356,854,442.85 yCRV (+182,468,898.58)
10 vault: 1,411,352.82 yCRV (-203,382,796.48)
10 hacker: 365,375,708.66 yCRV (+190,990,164.39)
11 vault: 21,556.65 yCRV (-204,772,592.65)
11 hacker: 364,931,677.30 yCRV (+190,546,133.03)
12 vault: 5.09 yCRV (-204,794,144.21)
12 hacker: 363,128,462.72 yCRV (+188,742,918.45)
13 vault: 0.00 yCRV (-204,794,149.30)
13 hacker: 361,312,825.47 yCRV (+186,927,281.20)
hacker has earned: +186,927,281.20
I think the test is robust enough to test the fix. I also changed to one iteration since any increase in hacker's balance should be considered a failure.
The test has failed as expected with hacker making it with 3.9 million, we can proceed with a fix that passes it.
> assert ycrv.balanceOf(hacker) <= before
E AssertionError: assert 178645048179063124162467674 <= 174735187241305314522350570
E + where 178645048179063124162467674 = <ContractCall 'balanceOf(address account)'>(<Account '0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11'>)
To prevent Evil Gauge attack in the future, besides access control in StrategyProxy, we better include a StrategyProxy.lock()
as a part of harvest()
routine in all the strategies that use it.
https://github.com/iearn-finance/yearn-protocol/pull/19#discussion_r500612532 I'm not sure if it works since the issue was on mainnet on a specific keeper configuration.