-
Notifications
You must be signed in to change notification settings - Fork 2
/
exploit.py
40 lines (30 loc) · 1.59 KB
/
exploit.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
'''
My solution to break this smart contract was:
if we look at UnstoppableLender contract we'll find a function called "depositTokens"
which its main goal seems be receiving the funds for the pool and update the
"poolBalance" variable.
Later, when the function in charge of processing the flash loan (flashLoan) is
executed there is an assert (line 40) checking that the balance before executing the
loan is the same as the poolBalance variable:
...
// Ensured by the protocol via the `depositTokens` function
assert(poolBalance == balanceBefore);
...
At first glance it seems that the only way to modify the value of the contract's
balance is calling "depositTokens", so this assert should be always True, as the
poolBalance variable is always updated.
The vulnerability is that the contract does not expect to receive tokens in any other
way. An attacker can abuse this asumption, issuing a transfer from its account. In
doing so it will be possible to modify the value of the contract's balance without
running the code in charge of updating the "poolBalance" variable.
When the left operand of the previous mentioned assertion is computed
...
uint256 balanceBefore = damnValuableToken.balanceOf(address(this));
...
the contract's balance is used. As the attacker has deposited Ether the balance won't
be equal to "poolBalance" variable value and therefore the assertion will fail
rendering the contract unusable.
'''
def exploit(pool, attacker_account, token):
print(f'Attacker balance: {token.balanceOf(attacker_account)}')
token.transfer(pool.address, '0.1 ether', {'from':attacker_account})