Skip to content

Commit abcc0e5

Browse files
Gas optimization on erc-20 (#182)
* added profiler * gas optimization * updated comment * Update contracts/UFragments.sol Co-authored-by: Brandon Iles <[email protected]> Co-authored-by: Brandon Iles <[email protected]>
1 parent aa041bc commit abcc0e5

File tree

5 files changed

+504
-29
lines changed

5 files changed

+504
-29
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ yarn format
6161

6262
# Run solidity coverage report (compatible with node v12)
6363
yarn coverage
64+
65+
# Run solidity gas usage report
66+
yarn profile
6467
```
6568

6669
## License

contracts/UFragments.sol

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -94,36 +94,40 @@ contract UFragments is ERC20Detailed, Ownable {
9494
onlyMonetaryPolicy
9595
returns (uint256)
9696
{
97+
uint256 oldTotalSupply = _totalSupply;
9798
if (supplyDelta == 0) {
98-
emit LogRebase(epoch, _totalSupply);
99-
return _totalSupply;
99+
emit LogRebase(epoch, oldTotalSupply);
100+
return oldTotalSupply;
100101
}
101102

103+
uint256 newTotalSupply;
102104
if (supplyDelta < 0) {
103-
_totalSupply = _totalSupply.sub(uint256(supplyDelta.abs()));
105+
newTotalSupply = oldTotalSupply.sub(uint256(supplyDelta.abs()));
104106
} else {
105-
_totalSupply = _totalSupply.add(uint256(supplyDelta));
107+
newTotalSupply = oldTotalSupply.add(uint256(supplyDelta));
106108
}
107109

108-
if (_totalSupply > MAX_SUPPLY) {
109-
_totalSupply = MAX_SUPPLY;
110+
if (newTotalSupply > MAX_SUPPLY) {
111+
newTotalSupply = MAX_SUPPLY;
110112
}
111113

112-
_gonsPerFragment = TOTAL_GONS.div(_totalSupply);
114+
_gonsPerFragment = TOTAL_GONS.div(newTotalSupply);
113115

114116
// From this point forward, _gonsPerFragment is taken as the source of truth.
115-
// We recalculate a new _totalSupply to be in agreement with the _gonsPerFragment
117+
// We recalculate a newTotalSupply to be in agreement with the _gonsPerFragment
116118
// conversion rate.
117119
// This means our applied supplyDelta can deviate from the requested supplyDelta,
118120
// but this deviation is guaranteed to be < (_totalSupply^2)/(TOTAL_GONS - _totalSupply).
119121
//
120122
// In the case of _totalSupply <= MAX_UINT128 (our current supply cap), this
121123
// deviation is guaranteed to be < 1, so we can omit this step. If the supply cap is
122124
// ever increased, it must be re-included.
123-
// _totalSupply = TOTAL_GONS.div(_gonsPerFragment)
125+
// newTotalSupply = TOTAL_GONS.div(_gonsPerFragment)
124126

125-
emit LogRebase(epoch, _totalSupply);
126-
return _totalSupply;
127+
_totalSupply = newTotalSupply;
128+
129+
emit LogRebase(epoch, newTotalSupply);
130+
return newTotalSupply;
127131
}
128132

129133
function initialize(address owner_) public initializer {
@@ -247,10 +251,11 @@ contract UFragments is ERC20Detailed, Ownable {
247251
* @param addedValue The amount of tokens to increase the allowance by.
248252
*/
249253
function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
250-
_allowedFragments[msg.sender][spender] = _allowedFragments[msg.sender][spender].add(
251-
addedValue
252-
);
253-
emit Approval(msg.sender, spender, _allowedFragments[msg.sender][spender]);
254+
uint256 oldValue = _allowedFragments[msg.sender][spender];
255+
uint256 newValue = oldValue.add(addedValue);
256+
257+
_allowedFragments[msg.sender][spender] = newValue;
258+
emit Approval(msg.sender, spender, newValue);
254259
return true;
255260
}
256261

@@ -262,12 +267,15 @@ contract UFragments is ERC20Detailed, Ownable {
262267
*/
263268
function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
264269
uint256 oldValue = _allowedFragments[msg.sender][spender];
270+
uint256 newValue;
265271
if (subtractedValue >= oldValue) {
266-
_allowedFragments[msg.sender][spender] = 0;
272+
newValue = 0;
267273
} else {
268-
_allowedFragments[msg.sender][spender] = oldValue.sub(subtractedValue);
274+
newValue = oldValue.sub(subtractedValue);
269275
}
270-
emit Approval(msg.sender, spender, _allowedFragments[msg.sender][spender]);
276+
277+
_allowedFragments[msg.sender][spender] = newValue;
278+
emit Approval(msg.sender, spender, newValue);
271279
return true;
272280
}
273281
}

hardhat.config.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import '@nomiclabs/hardhat-ethers'
44
import '@nomiclabs/hardhat-waffle'
55
import '@openzeppelin/hardhat-upgrades'
66
import 'solidity-coverage'
7+
import 'hardhat-gas-reporter'
78

89
require('./scripts/deploy')
910

@@ -14,4 +15,9 @@ export default {
1415
mocha: {
1516
timeout: 100000,
1617
},
18+
gasReporter: {
19+
currency: 'USD',
20+
enabled: process.env.REPORT_GAS ? true : false,
21+
excludeContracts: ['mocks/'],
22+
},
1723
} as HardhatUserConfig

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"scripts": {
2121
"compile": "yarn hardhat compile",
2222
"test": "yarn hardhat test",
23+
"profile": "REPORT_GAS=true yarn hardhat test test/unit/*.ts",
2324
"coverage": "yarn hardhat coverage --testfiles 'test/unit/*.ts'",
2425
"format": "yarn prettier --config .prettierrc --write '**/*.ts' 'contracts/**/*.sol'",
2526
"lint": "yarn solhint 'contracts/**/*.sol'"
@@ -52,6 +53,7 @@
5253
"typescript": "^4.0.2"
5354
},
5455
"dependencies": {
56+
"hardhat-gas-reporter": "^1.0.4",
5557
"openzeppelin-eth": "2.0.2-standalone"
5658
}
5759
}

0 commit comments

Comments
 (0)