From 4feb97afc8f23b1bf5f89b2a3c8bb18f9c8f8923 Mon Sep 17 00:00:00 2001 From: Facu Spagnuolo Date: Mon, 15 Jul 2019 13:05:59 -0300 Subject: [PATCH] SafeERC20: Add safe total supply (#543) --- contracts/common/SafeERC20.sol | 13 +++++++++++++ contracts/test/mocks/lib/token/SafeERC20Mock.sol | 4 ++++ test/contracts/common/safe_erc20.js | 6 ++++++ 3 files changed, 23 insertions(+) diff --git a/contracts/common/SafeERC20.sol b/contracts/common/SafeERC20.sol index fa11c0921..9a6afd27b 100644 --- a/contracts/common/SafeERC20.sol +++ b/contracts/common/SafeERC20.sol @@ -153,4 +153,17 @@ library SafeERC20 { return allowance; } + + /** + * @dev Static call into ERC20.totalSupply(). + * Reverts if the call fails for some reason (should never fail). + */ + function staticTotalSupply(ERC20 _token) internal view returns (uint256) { + bytes memory totalSupplyCallData = abi.encodeWithSelector(_token.totalSupply.selector); + + (bool success, uint256 totalSupply) = staticInvoke(_token, totalSupplyCallData); + require(success, ERROR_TOKEN_ALLOWANCE_REVERTED); + + return totalSupply; + } } diff --git a/contracts/test/mocks/lib/token/SafeERC20Mock.sol b/contracts/test/mocks/lib/token/SafeERC20Mock.sol index 9f13848f6..d1f83369d 100644 --- a/contracts/test/mocks/lib/token/SafeERC20Mock.sol +++ b/contracts/test/mocks/lib/token/SafeERC20Mock.sol @@ -33,4 +33,8 @@ contract SafeERC20Mock { function balanceOf(ERC20 token, address owner) external view returns (uint256) { return token.staticBalanceOf(owner); } + + function totalSupply(ERC20 token) external view returns (uint256) { + return token.staticTotalSupply(); + } } diff --git a/test/contracts/common/safe_erc20.js b/test/contracts/common/safe_erc20.js index 00c08a311..2b8d58505 100644 --- a/test/contracts/common/safe_erc20.js +++ b/test/contracts/common/safe_erc20.js @@ -120,6 +120,12 @@ contract('SafeERC20', ([owner, receiver]) => { assert.equal(balance, initialBalance, 'Mock should return correct balance') assert.equal((await tokenMock.balanceOf(owner)).valueOf(), balance, "Mock should match token contract's balance") }) + + it('gives correct value with static totalSupply', async () => { + const totalSupply = (await safeERC20Mock.totalSupply(tokenMock.address)).valueOf() + assert.equal(totalSupply, initialBalance, 'Mock should return correct total supply') + assert.equal((await tokenMock.totalSupply()).valueOf(), totalSupply, "Mock should match token contract's total supply") + }) }) } })