From 6d97f0919547df11be9443b54af2d90631eaa733 Mon Sep 17 00:00:00 2001 From: rotcivegaf Date: Sat, 10 Jul 2021 21:28:12 +0200 Subject: [PATCH] Gas optimization on average function of Math.sol (#2757) * change implementation to save gas * add average test with two max uni256 number --- contracts/utils/math/Math.sol | 4 ++-- test/utils/math/Math.test.js | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/contracts/utils/math/Math.sol b/contracts/utils/math/Math.sol index 66bb22005..7280bddeb 100644 --- a/contracts/utils/math/Math.sol +++ b/contracts/utils/math/Math.sol @@ -25,8 +25,8 @@ library Math { * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { - // (a + b) / 2 can overflow, so we distribute. - return (a / 2) + (b / 2) + (((a % 2) + (b % 2)) / 2); + // (a + b) / 2 can overflow. + return (a & b) + (a ^ b) / 2; } /** diff --git a/test/utils/math/Math.test.js b/test/utils/math/Math.test.js index 31d3e17ac..7e194dec7 100644 --- a/test/utils/math/Math.test.js +++ b/test/utils/math/Math.test.js @@ -54,6 +54,11 @@ contract('Math', function (accounts) { const b = new BN('84346'); expect(await this.math.average(a, b)).to.be.bignumber.equal(bnAverage(a, b)); }); + + it('is correctly calculated with two max uint256 numbers', async function () { + const a = MAX_UINT256; + expect(await this.math.average(a, a)).to.be.bignumber.equal(bnAverage(a, a)); + }); }); describe('ceilDiv', function () {