parent
af6fdae3dd
commit
c7636bdc4c
@ -0,0 +1,22 @@ |
|||||||
|
pragma solidity ^0.4.11; |
||||||
|
|
||||||
|
import './ERC20Basic.sol'; |
||||||
|
import './ERC20.sol'; |
||||||
|
|
||||||
|
/** |
||||||
|
* @title SafeERC20 |
||||||
|
* @dev Wrappers around ERC20 operations that throw on failure. |
||||||
|
*/ |
||||||
|
library SafeERC20 { |
||||||
|
function safeTransfer(ERC20Basic token, address to, uint256 value) internal { |
||||||
|
assert(token.transfer(to, value)); |
||||||
|
} |
||||||
|
|
||||||
|
function safeTransferFrom(ERC20 token, address from, address to, uint256 value) internal { |
||||||
|
assert(token.transferFrom(from, to, value)); |
||||||
|
} |
||||||
|
|
||||||
|
function safeApprove(ERC20 token, address spender, uint256 value) internal { |
||||||
|
assert(token.approve(spender, value)); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
import EVMThrow from './helpers/EVMThrow'; |
||||||
|
|
||||||
|
require('chai') |
||||||
|
.use(require('chai-as-promised')) |
||||||
|
.should(); |
||||||
|
|
||||||
|
const SafeERC20Helper = artifacts.require('./helpers/SafeERC20Helper.sol'); |
||||||
|
|
||||||
|
contract('SafeERC20', function () { |
||||||
|
|
||||||
|
beforeEach(async function () { |
||||||
|
this.helper = await SafeERC20Helper.new(); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should throw on failed transfer', async function () { |
||||||
|
await this.helper.doFailingTransfer().should.be.rejectedWith(EVMThrow); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should throw on failed transferFrom', async function () { |
||||||
|
await this.helper.doFailingTransferFrom().should.be.rejectedWith(EVMThrow); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should throw on failed approve', async function () { |
||||||
|
await this.helper.doFailingApprove().should.be.rejectedWith(EVMThrow); |
||||||
|
}); |
||||||
|
|
||||||
|
}); |
@ -0,0 +1,48 @@ |
|||||||
|
pragma solidity ^0.4.11; |
||||||
|
|
||||||
|
import '../../contracts/token/ERC20.sol'; |
||||||
|
import '../../contracts/token/SafeERC20.sol'; |
||||||
|
|
||||||
|
contract ERC20FailingMock is ERC20 { |
||||||
|
function transfer(address, uint256) returns (bool) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
function transferFrom(address, address, uint256) returns (bool) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
function approve(address, uint256) returns (bool) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
function balanceOf(address) constant returns (uint256) { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
function allowance(address, address) constant returns (uint256) { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract SafeERC20Helper { |
||||||
|
using SafeERC20 for ERC20; |
||||||
|
|
||||||
|
ERC20 token; |
||||||
|
|
||||||
|
function SafeERC20Helper() { |
||||||
|
token = new ERC20FailingMock(); |
||||||
|
} |
||||||
|
|
||||||
|
function doFailingTransfer() { |
||||||
|
token.safeTransfer(0, 0); |
||||||
|
} |
||||||
|
|
||||||
|
function doFailingTransferFrom() { |
||||||
|
token.safeTransferFrom(0, 0, 0); |
||||||
|
} |
||||||
|
|
||||||
|
function doFailingApprove() { |
||||||
|
token.safeApprove(0, 0); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue