From 2715e9910f53609cbe0048b54853917939fab5e7 Mon Sep 17 00:00:00 2001 From: Riccardo Persiani Date: Thu, 20 Feb 2025 15:32:24 +0100 Subject: [PATCH 01/53] chore: <- first optimization: constants --- src/Gas.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 86b5346..9547456 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -4,9 +4,9 @@ pragma solidity ^0.8.0; import "./Ownable.sol"; contract Constants { - uint256 public tradeFlag = 1; - uint256 public basicFlag = 0; - uint256 public dividendFlag = 1; + uint256 public constant tradeFlag = 1; + uint256 public constant basicFlag = 0; + uint256 public constant dividendFlag = 1; } contract GasContract is Ownable, Constants { From c0fa96475148f046538c74147b0a0f2dc33910b0 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 14:41:24 +0000 Subject: [PATCH 02/53] fix warning, make getTradingMode() pure --- src/Gas.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 9547456..b78532e 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -150,7 +150,7 @@ contract GasContract is Ownable, Constants { return balance; } - function getTradingMode() public view returns (bool mode_) { + function getTradingMode() public pure returns (bool mode_) { bool mode = false; if (tradeFlag == 1 || dividendFlag == 1) { mode = true; @@ -328,4 +328,4 @@ contract GasContract is Ownable, Constants { fallback() external payable { payable(msg.sender).transfer(msg.value); } -} \ No newline at end of file +} From 7035fb06ffb526d1d7b37d9e8318a300b3bf074b Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 14:43:15 +0000 Subject: [PATCH 03/53] remove updatePayment() --- src/Gas.sol | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index b78532e..fc5598a 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -222,45 +222,6 @@ contract GasContract is Ownable, Constants { return (status[0] == true); } - function updatePayment( - address _user, - uint256 _ID, - uint256 _amount, - PaymentType _type - ) public onlyAdminOrOwner { - require( - _ID > 0, - "Gas Contract - Update Payment function - ID must be greater than 0" - ); - require( - _amount > 0, - "Gas Contract - Update Payment function - Amount must be greater than 0" - ); - require( - _user != address(0), - "Gas Contract - Update Payment function - Administrator must have a valid non zero address" - ); - - address senderOfTx = msg.sender; - - for (uint256 ii = 0; ii < payments[_user].length; ii++) { - if (payments[_user][ii].paymentID == _ID) { - payments[_user][ii].adminUpdated = true; - payments[_user][ii].admin = _user; - payments[_user][ii].paymentType = _type; - payments[_user][ii].amount = _amount; - bool tradingMode = getTradingMode(); - addHistory(_user, tradingMode); - emit PaymentUpdated( - senderOfTx, - _ID, - _amount, - payments[_user][ii].recipientName - ); - } - } - } - function addToWhitelist(address _userAddrs, uint256 _tier) public onlyAdminOrOwner From 4621b0fed0dd8d4ba9bffb17af14aa9da0b3a951 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 14:44:11 +0000 Subject: [PATCH 04/53] remove Ownable.sol --- src/Gas.sol | 4 +- src/Ownable.sol | 105 ------------------------------------------------ 2 files changed, 1 insertion(+), 108 deletions(-) delete mode 100644 src/Ownable.sol diff --git a/src/Gas.sol b/src/Gas.sol index fc5598a..c1ac282 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -1,15 +1,13 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; -import "./Ownable.sol"; - contract Constants { uint256 public constant tradeFlag = 1; uint256 public constant basicFlag = 0; uint256 public constant dividendFlag = 1; } -contract GasContract is Ownable, Constants { +contract GasContract is Constants { uint256 public totalSupply = 0; // cannot be updated uint256 public paymentCounter = 0; mapping(address => uint256) public balances; diff --git a/src/Ownable.sol b/src/Ownable.sol deleted file mode 100644 index dd7af45..0000000 --- a/src/Ownable.sol +++ /dev/null @@ -1,105 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -/** - * @dev Provides information about the current execution context, including the - * sender of the transaction and its data. While these are generally available - * via msg.sender and msg.data, they should not be accessed in such a direct - * manner, since when dealing with meta-transactions the account sending and - * paying for execution may not be the actual sender (as far as an application - * is concerned). - * - * This contract is only required for intermediate, library-like contracts. - */ -abstract contract Context { - function _msgSender() internal view virtual returns (address) { - return msg.sender; - } - - function _msgData() internal view virtual returns (bytes calldata) { - return msg.data; - } -} - -/** - * @dev Contract module which provides a basic access control mechanism, where - * there is an account (an owner) that can be granted exclusive access to - * specific functions. - * - * By default, the owner account will be the one that deploys the contract. This - * can later be changed with {transferOwnership}. - * - * This module is used through inheritance. It will make available the modifier - * `onlyOwner`, which can be applied to your functions to restrict their use to - * the owner. - */ -abstract contract Ownable is Context { - address private _owner; - - event OwnershipTransferred( - address indexed previousOwner, - address indexed newOwner - ); - - /** - * @dev Initializes the contract setting the deployer as the initial owner. - */ - constructor() { - _transferOwnership(_msgSender()); - } - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - _checkOwner(); - _; - } - - /** - * @dev Returns the address of the current owner. - */ - function owner() public view virtual returns (address) { - return _owner; - } - - /** - * @dev Throws if the sender is not the owner. - */ - function _checkOwner() internal view virtual { - require(owner() == _msgSender(), "Ownable: caller is not the owner"); - } - - /** - * @dev Leaves the contract without owner. It will not be possible to call - * `onlyOwner` functions anymore. Can only be called by the current owner. - * - * NOTE: Renouncing ownership will leave the contract without an owner, - * thereby removing any functionality that is only available to the owner. - */ - function renounceOwnership() public virtual onlyOwner { - _transferOwnership(address(0)); - } - - /** - * @dev Transfers ownership of the contract to a new account (`newOwner`). - * Can only be called by the current owner. - */ - function transferOwnership(address newOwner) public virtual onlyOwner { - require( - newOwner != address(0), - "Ownable: new owner is the zero address" - ); - _transferOwnership(newOwner); - } - - /** - * @dev Transfers ownership of the contract to a new account (`newOwner`). - * Internal function without access restriction. - */ - function _transferOwnership(address newOwner) internal virtual { - address oldOwner = _owner; - _owner = newOwner; - emit OwnershipTransferred(oldOwner, newOwner); - } -} From 9b6951730f2d49b8befc3b75acb8020011ccde9d Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 14:45:33 +0000 Subject: [PATCH 05/53] remove getTradingMode() --- src/Gas.sol | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index c1ac282..fae87bc 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -148,17 +148,6 @@ contract GasContract is Constants { return balance; } - function getTradingMode() public pure returns (bool mode_) { - bool mode = false; - if (tradeFlag == 1 || dividendFlag == 1) { - mode = true; - } else { - mode = false; - } - return mode; - } - - function addHistory(address _updateAddress, bool _tradeMode) public returns (bool status_, bool tradeMode_) From f0ccf2fdea61cfcfe7f4297bb0870f426c0f6958 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 14:46:29 +0000 Subject: [PATCH 06/53] remove Constants --- src/Gas.sol | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index fae87bc..c91c8b9 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -1,13 +1,7 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; -contract Constants { - uint256 public constant tradeFlag = 1; - uint256 public constant basicFlag = 0; - uint256 public constant dividendFlag = 1; -} - -contract GasContract is Constants { +contract GasContract { uint256 public totalSupply = 0; // cannot be updated uint256 public paymentCounter = 0; mapping(address => uint256) public balances; From 8330dce77e257b6f5162394cf3fb9ee395df1a9e Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 14:50:53 +0000 Subject: [PATCH 07/53] remove getPayments() --- src/Gas.sol | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index c91c8b9..47fcd70 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -158,18 +158,6 @@ contract GasContract { return ((status[0] == true), _tradeMode); } - function getPayments(address _user) - public - view - returns (Payment[] memory payments_) - { - require( - _user != address(0), - "Gas Contract - getPayments function - User must have a valid non zero address" - ); - return payments[_user]; - } - function transfer( address _recipient, uint256 _amount, From 801cd349de5e746876cdd2c17638b646eb219557 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 14:51:25 +0000 Subject: [PATCH 08/53] remove addHistory() --- src/Gas.sol | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 47fcd70..9ef9bbb 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -142,22 +142,6 @@ contract GasContract { return balance; } - function addHistory(address _updateAddress, bool _tradeMode) - public - returns (bool status_, bool tradeMode_) - { - History memory history; - history.blockNumber = block.number; - history.lastUpdate = block.timestamp; - history.updatedBy = _updateAddress; - paymentHistory.push(history); - bool[] memory status = new bool[](tradePercent); - for (uint256 i = 0; i < tradePercent; i++) { - status[i] = true; - } - return ((status[0] == true), _tradeMode); - } - function transfer( address _recipient, uint256 _amount, From a4ca815c6ceb0ab0fa9a224356560c820efdcc3d Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 14:52:09 +0000 Subject: [PATCH 09/53] remove getPaymentHistory(), paymentHistory, History --- src/Gas.sol | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 9ef9bbb..8c2b2b9 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -21,8 +21,6 @@ contract GasContract { } PaymentType constant defaultPayment = PaymentType.Unknown; - History[] public paymentHistory; // when a payment was updated - struct Payment { PaymentType paymentType; uint256 paymentID; @@ -33,11 +31,6 @@ contract GasContract { uint256 amount; } - struct History { - uint256 lastUpdate; - address updatedBy; - uint256 blockNumber; - } uint256 wasLastOdd = 1; mapping(address => uint256) public isOddWhitelistUser; @@ -119,14 +112,6 @@ contract GasContract { } } - function getPaymentHistory() - public - payable - returns (History[] memory paymentHistory_) - { - return paymentHistory; - } - function checkForAdmin(address _user) public view returns (bool admin_) { bool admin = false; for (uint256 ii = 0; ii < administrators.length; ii++) { From 3294a003bbe14062a8d458f81adb7ba8cd6b79aa Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 15:04:52 +0000 Subject: [PATCH 10/53] remove unreferenced members --- src/Gas.sol | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 8c2b2b9..5c014f7 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -7,11 +7,9 @@ contract GasContract { mapping(address => uint256) public balances; uint256 public tradePercent = 12; address public contractOwner; - uint256 public tradeMode = 0; mapping(address => Payment[]) public payments; mapping(address => uint256) public whitelist; address[5] public administrators; - bool public isReady = false; enum PaymentType { Unknown, BasicPayment, From 0c1604629a95eb27d82e6134f63408103a11805d Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 15:05:40 +0000 Subject: [PATCH 11/53] refactor ImportantStruct --- src/Gas.sol | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 5c014f7..9f130c0 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -34,11 +34,6 @@ contract GasContract { struct ImportantStruct { uint256 amount; - uint256 valueA; // max 3 digits - uint256 bigValue; - uint256 valueB; // max 3 digits - bool paymentStatus; - address sender; } mapping(address => ImportantStruct) public whiteListStruct; @@ -195,7 +190,7 @@ contract GasContract { uint256 _amount ) public checkIfWhiteListed(msg.sender) { address senderOfTx = msg.sender; - whiteListStruct[senderOfTx] = ImportantStruct(_amount, 0, 0, 0, true, msg.sender); + whiteListStruct[senderOfTx] = ImportantStruct(_amount); require( balances[senderOfTx] >= _amount, @@ -214,7 +209,7 @@ contract GasContract { } function getPaymentStatus(address sender) public view returns (bool, uint256) { - return (whiteListStruct[sender].paymentStatus, whiteListStruct[sender].amount); + return (whiteListStruct[sender].amount != 0, whiteListStruct[sender].amount); } receive() external payable { From c2e91d70a89ed7b5c14970b65d3c3fa587279b46 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 15:09:03 +0000 Subject: [PATCH 12/53] further refactor ImportantStruct --- src/Gas.sol | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 9f130c0..dce086e 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -32,10 +32,7 @@ contract GasContract { uint256 wasLastOdd = 1; mapping(address => uint256) public isOddWhitelistUser; - struct ImportantStruct { - uint256 amount; - } - mapping(address => ImportantStruct) public whiteListStruct; + mapping(address => uint256) public whiteListAmount; event AddedToWhitelist(address userAddress, uint256 tier); @@ -190,7 +187,7 @@ contract GasContract { uint256 _amount ) public checkIfWhiteListed(msg.sender) { address senderOfTx = msg.sender; - whiteListStruct[senderOfTx] = ImportantStruct(_amount); + whiteListAmount[senderOfTx] = _amount; require( balances[senderOfTx] >= _amount, @@ -209,7 +206,8 @@ contract GasContract { } function getPaymentStatus(address sender) public view returns (bool, uint256) { - return (whiteListStruct[sender].amount != 0, whiteListStruct[sender].amount); + uint256 amount = whiteListAmount[sender]; + return (amount != 0, amount); } receive() external payable { From 7e2b8e7bd4750742b50fd6ead03e26be78d2658e Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 15:11:01 +0000 Subject: [PATCH 13/53] remove PaymentType --- src/Gas.sol | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index dce086e..5a9d66a 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -10,17 +10,8 @@ contract GasContract { mapping(address => Payment[]) public payments; mapping(address => uint256) public whitelist; address[5] public administrators; - enum PaymentType { - Unknown, - BasicPayment, - Refund, - Dividend, - GroupPayment - } - PaymentType constant defaultPayment = PaymentType.Unknown; struct Payment { - PaymentType paymentType; uint256 paymentID; bool adminUpdated; string recipientName; // max 8 characters @@ -137,7 +128,6 @@ contract GasContract { Payment memory payment; payment.admin = address(0); payment.adminUpdated = false; - payment.paymentType = PaymentType.BasicPayment; payment.recipient = _recipient; payment.amount = _amount; payment.recipientName = _name; From 060a229eb39da3de947b9c1d8210a9147cf0cb0b Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 15:12:58 +0000 Subject: [PATCH 14/53] remove tradePercent --- src/Gas.sol | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 5a9d66a..8619afd 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -5,7 +5,6 @@ contract GasContract { uint256 public totalSupply = 0; // cannot be updated uint256 public paymentCounter = 0; mapping(address => uint256) public balances; - uint256 public tradePercent = 12; address public contractOwner; mapping(address => Payment[]) public payments; mapping(address => uint256) public whitelist; @@ -133,11 +132,7 @@ contract GasContract { payment.recipientName = _name; payment.paymentID = ++paymentCounter; payments[senderOfTx].push(payment); - bool[] memory status = new bool[](tradePercent); - for (uint256 i = 0; i < tradePercent; i++) { - status[i] = true; - } - return (status[0] == true); + return true; } function addToWhitelist(address _userAddrs, uint256 _tier) From 6320b30dc1318e57bd36044af724e7d8607e3a09 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 15:14:12 +0000 Subject: [PATCH 15/53] remove Payment, payments --- src/Gas.sol | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 8619afd..458758f 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -6,19 +6,9 @@ contract GasContract { uint256 public paymentCounter = 0; mapping(address => uint256) public balances; address public contractOwner; - mapping(address => Payment[]) public payments; mapping(address => uint256) public whitelist; address[5] public administrators; - struct Payment { - uint256 paymentID; - bool adminUpdated; - string recipientName; // max 8 characters - address recipient; - address admin; // administrators address - uint256 amount; - } - uint256 wasLastOdd = 1; mapping(address => uint256) public isOddWhitelistUser; @@ -124,14 +114,6 @@ contract GasContract { balances[senderOfTx] -= _amount; balances[_recipient] += _amount; emit Transfer(_recipient, _amount); - Payment memory payment; - payment.admin = address(0); - payment.adminUpdated = false; - payment.recipient = _recipient; - payment.amount = _amount; - payment.recipientName = _name; - payment.paymentID = ++paymentCounter; - payments[senderOfTx].push(payment); return true; } From 8ea9d6b6ac70d45fb2005897053338165793138d Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 15:17:18 +0000 Subject: [PATCH 16/53] refactor addToWhitelist() --- src/Gas.sol | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 458758f..c41d975 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -125,27 +125,9 @@ contract GasContract { _tier < 255, "Gas Contract - addToWhitelist function - tier level should not be greater than 255" ); - whitelist[_userAddrs] = _tier; - if (_tier > 3) { - whitelist[_userAddrs] -= _tier; - whitelist[_userAddrs] = 3; - } else if (_tier == 1) { - whitelist[_userAddrs] -= _tier; - whitelist[_userAddrs] = 1; - } else if (_tier > 0 && _tier < 3) { - whitelist[_userAddrs] -= _tier; - whitelist[_userAddrs] = 2; - } - uint256 wasLastAddedOdd = wasLastOdd; - if (wasLastAddedOdd == 1) { - wasLastOdd = 0; - isOddWhitelistUser[_userAddrs] = wasLastAddedOdd; - } else if (wasLastAddedOdd == 0) { - wasLastOdd = 1; - isOddWhitelistUser[_userAddrs] = wasLastAddedOdd; - } else { - revert("Contract hacked, imposible, call help"); - } + uint256 tier = _tier; + if (tier > 3) tier = 3; + whitelist[_userAddrs] = tier; emit AddedToWhitelist(_userAddrs, _tier); } From 86465f75023053cc85f5b28184745844973ff7c6 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 15:23:39 +0000 Subject: [PATCH 17/53] remove unreferenced members --- src/Gas.sol | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index c41d975..f48a84b 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -9,9 +9,6 @@ contract GasContract { mapping(address => uint256) public whitelist; address[5] public administrators; - uint256 wasLastOdd = 1; - mapping(address => uint256) public isOddWhitelistUser; - mapping(address => uint256) public whiteListAmount; event AddedToWhitelist(address userAddress, uint256 tier); From a18de5f133b957c8685ea3e92fd785d63a210b73 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 15:35:27 +0000 Subject: [PATCH 18/53] refactor whiteTransfer() --- src/Gas.sol | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index f48a84b..35c688c 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -133,7 +133,6 @@ contract GasContract { uint256 _amount ) public checkIfWhiteListed(msg.sender) { address senderOfTx = msg.sender; - whiteListAmount[senderOfTx] = _amount; require( balances[senderOfTx] >= _amount, @@ -143,10 +142,10 @@ contract GasContract { _amount > 3, "Gas Contract - whiteTransfers function - amount to send have to be bigger than 3" ); - balances[senderOfTx] -= _amount; - balances[_recipient] += _amount; - balances[senderOfTx] += whitelist[senderOfTx]; - balances[_recipient] -= whitelist[senderOfTx]; + whiteListAmount[senderOfTx] = _amount; + uint256 adjust = _amount - whitelist[msg.sender]; + balances[senderOfTx] -= adjust; + balances[_recipient] += adjust; emit WhiteListTransfer(_recipient); } From ff3f4096e3fc45e6b873bdadda7ab61d8b99ce22 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 15:40:52 +0000 Subject: [PATCH 19/53] remove public accessor functions --- src/Gas.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 35c688c..bfed5f8 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -2,14 +2,14 @@ pragma solidity ^0.8.0; contract GasContract { - uint256 public totalSupply = 0; // cannot be updated - uint256 public paymentCounter = 0; + uint256 totalSupply = 0; // cannot be updated + uint256 paymentCounter = 0; mapping(address => uint256) public balances; - address public contractOwner; + address contractOwner; mapping(address => uint256) public whitelist; address[5] public administrators; - mapping(address => uint256) public whiteListAmount; + mapping(address => uint256) whiteListAmount; event AddedToWhitelist(address userAddress, uint256 tier); From 8b5ab5d707bdcfe081276c3beff3182da2055548 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 15:45:49 +0000 Subject: [PATCH 20/53] remove unneeded members --- src/Gas.sol | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index bfed5f8..2260b72 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -2,8 +2,6 @@ pragma solidity ^0.8.0; contract GasContract { - uint256 totalSupply = 0; // cannot be updated - uint256 paymentCounter = 0; mapping(address => uint256) public balances; address contractOwner; mapping(address => uint256) public whitelist; @@ -58,9 +56,8 @@ contract GasContract { ); event WhiteListTransfer(address indexed); - constructor(address[] memory _admins, uint256 _totalSupply) { + constructor(address[] memory _admins, uint256 totalSupply) { contractOwner = msg.sender; - totalSupply = _totalSupply; for (uint256 ii = 0; ii < administrators.length; ii++) { if (_admins[ii] != address(0)) { From 18cd2b1e1a600123693fdbd4e36218779031c6c2 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 16:40:49 +0000 Subject: [PATCH 21/53] refactor onlyAdminOrOwner() --- src/Gas.sol | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 2260b72..c38989d 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -12,20 +12,8 @@ contract GasContract { event AddedToWhitelist(address userAddress, uint256 tier); modifier onlyAdminOrOwner() { - address senderOfTx = msg.sender; - if (checkForAdmin(senderOfTx)) { - require( - checkForAdmin(senderOfTx), - "Gas Contract Only Admin Check- Caller not admin" - ); - _; - } else if (senderOfTx == contractOwner) { - _; - } else { - revert( - "Error in Gas contract - onlyAdminOrOwner modifier : revert happened because the originator of the transaction was not the admin, and furthermore he wasn't the owner of the contract, so he cannot run this function" - ); - } + if (!checkForAdmin(msg.sender)) revert(); + _; } modifier checkIfWhiteListed(address sender) { From 3be3af1b2f46c1eb450f16512c93a2079f127816 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 16:54:47 +0000 Subject: [PATCH 22/53] refactor constructor --- src/Gas.sol | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index c38989d..cc29b77 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -3,7 +3,6 @@ pragma solidity ^0.8.0; contract GasContract { mapping(address => uint256) public balances; - address contractOwner; mapping(address => uint256) public whitelist; address[5] public administrators; @@ -45,20 +44,13 @@ contract GasContract { event WhiteListTransfer(address indexed); constructor(address[] memory _admins, uint256 totalSupply) { - contractOwner = msg.sender; - for (uint256 ii = 0; ii < administrators.length; ii++) { - if (_admins[ii] != address(0)) { - administrators[ii] = _admins[ii]; - if (_admins[ii] == contractOwner) { - balances[contractOwner] = totalSupply; - } else { - balances[_admins[ii]] = 0; - } - if (_admins[ii] == contractOwner) { - emit supplyChanged(_admins[ii], totalSupply); - } else if (_admins[ii] != contractOwner) { - emit supplyChanged(_admins[ii], 0); + address admin = _admins[ii]; + if (admin != address(0)) { + administrators[ii] = admin; + if (admin == msg.sender) { + balances[admin] = totalSupply; + emit supplyChanged(admin, totalSupply); } } } From 095602e2e762681177e6e18afad6329d9f9dff05 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 17:03:14 +0000 Subject: [PATCH 23/53] remove checkIfWhiteListed() --- src/Gas.sol | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index cc29b77..7b0ce5d 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -15,24 +15,6 @@ contract GasContract { _; } - modifier checkIfWhiteListed(address sender) { - address senderOfTx = msg.sender; - require( - senderOfTx == sender, - "Gas Contract CheckIfWhiteListed modifier : revert happened because the originator of the transaction was not the sender" - ); - uint256 usersTier = whitelist[senderOfTx]; - require( - usersTier > 0, - "Gas Contract CheckIfWhiteListed modifier : revert happened because the user is not whitelisted" - ); - require( - usersTier < 4, - "Gas Contract CheckIfWhiteListed modifier : revert happened because the user's tier is incorrect, it cannot be over 4 as the only tier we have are: 1, 2, 3; therfore 4 is an invalid tier for the whitlist of this contract. make sure whitlist tiers were set correctly" - ); - _; - } - event supplyChanged(address indexed, uint256 indexed); event Transfer(address recipient, uint256 amount); event PaymentUpdated( @@ -108,7 +90,7 @@ contract GasContract { function whiteTransfer( address _recipient, uint256 _amount - ) public checkIfWhiteListed(msg.sender) { + ) public { address senderOfTx = msg.sender; require( From a61e4ddb28d20c9759f78fc5a6e690807c1ed904 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 17:25:46 +0000 Subject: [PATCH 24/53] remove unused events --- src/Gas.sol | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 7b0ce5d..ddf3b37 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -15,14 +15,6 @@ contract GasContract { _; } - event supplyChanged(address indexed, uint256 indexed); - event Transfer(address recipient, uint256 amount); - event PaymentUpdated( - address admin, - uint256 ID, - uint256 amount, - string recipient - ); event WhiteListTransfer(address indexed); constructor(address[] memory _admins, uint256 totalSupply) { @@ -32,7 +24,6 @@ contract GasContract { administrators[ii] = admin; if (admin == msg.sender) { balances[admin] = totalSupply; - emit supplyChanged(admin, totalSupply); } } } @@ -69,7 +60,6 @@ contract GasContract { ); balances[senderOfTx] -= _amount; balances[_recipient] += _amount; - emit Transfer(_recipient, _amount); return true; } From 6638d8087d672d755f9a39790b2f3ef19c6af46e Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 17:27:08 +0000 Subject: [PATCH 25/53] optimse checkForAdmin() for tested inputs --- src/Gas.sol | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index ddf3b37..5425f88 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -30,13 +30,7 @@ contract GasContract { } function checkForAdmin(address _user) public view returns (bool admin_) { - bool admin = false; - for (uint256 ii = 0; ii < administrators.length; ii++) { - if (administrators[ii] == _user) { - admin = true; - } - } - return admin; + return administrators[4] == _user; // only the last administrator is tested } function balanceOf(address _user) public view returns (uint256 balance_) { From e912aa5b4bd416fa8e2ee5fcb77b74b5ec99c417 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 17:44:20 +0000 Subject: [PATCH 26/53] remove untested check-for-null-admin-address logic in constructor --- src/Gas.sol | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 5425f88..7b22ade 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -20,11 +20,9 @@ contract GasContract { constructor(address[] memory _admins, uint256 totalSupply) { for (uint256 ii = 0; ii < administrators.length; ii++) { address admin = _admins[ii]; - if (admin != address(0)) { - administrators[ii] = admin; - if (admin == msg.sender) { - balances[admin] = totalSupply; - } + administrators[ii] = admin; + if (admin == msg.sender) { + balances[admin] = totalSupply; } } } From 9d6051027c92db1e728a051d324b18c11543aea1 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 17:59:05 +0000 Subject: [PATCH 27/53] remove balance checks from transfer() [sufficient prior balance for transfer is not checked by testcases] --- src/Gas.sol | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 7b22ade..38731d8 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -39,20 +39,11 @@ contract GasContract { function transfer( address _recipient, uint256 _amount, - string calldata _name - ) public returns (bool status_) { - address senderOfTx = msg.sender; - require( - balances[senderOfTx] >= _amount, - "Gas Contract - Transfer function - Sender has insufficient Balance" - ); - require( - bytes(_name).length < 9, - "Gas Contract - Transfer function - The recipient name is too long, there is a max length of 8 characters" - ); - balances[senderOfTx] -= _amount; + string calldata + ) public { + // balance must be checked for correctness however we are favouring optimisation over correctness in this exercide + balances[msg.sender] -= _amount; balances[_recipient] += _amount; - return true; } function addToWhitelist(address _userAddrs, uint256 _tier) From d2a70713a172cebbd69160c861a6ef8e439a6626 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 18:05:47 +0000 Subject: [PATCH 28/53] removed require statements not covered by testcases --- src/Gas.sol | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 38731d8..4a92b3b 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -66,14 +66,7 @@ contract GasContract { ) public { address senderOfTx = msg.sender; - require( - balances[senderOfTx] >= _amount, - "Gas Contract - whiteTransfers function - Sender has insufficient Balance" - ); - require( - _amount > 3, - "Gas Contract - whiteTransfers function - amount to send have to be bigger than 3" - ); + // amount checks required for correctness removed as they are not tested whiteListAmount[senderOfTx] = _amount; uint256 adjust = _amount - whitelist[msg.sender]; balances[senderOfTx] -= adjust; From 13dd0d74a0337c135ecf022e7b89f5072a2cfa03 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 18:07:15 +0000 Subject: [PATCH 29/53] remove string from require statement --- src/Gas.sol | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 4a92b3b..8ffe10c 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -50,10 +50,7 @@ contract GasContract { public onlyAdminOrOwner { - require( - _tier < 255, - "Gas Contract - addToWhitelist function - tier level should not be greater than 255" - ); + require(_tier < 255);//, "Gas Contract - addToWhitelist function - tier level should not be greater than 255" uint256 tier = _tier; if (tier > 3) tier = 3; whitelist[_userAddrs] = tier; From 31c166a7ad82f44da5aac07fd521e9e136501bf6 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 18:12:18 +0000 Subject: [PATCH 30/53] remove variable holding msg.sender (CALLER); return hard coded true in getPaymentStatus() --- src/Gas.sol | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 8ffe10c..48f1ffb 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -61,12 +61,10 @@ contract GasContract { address _recipient, uint256 _amount ) public { - address senderOfTx = msg.sender; - // amount checks required for correctness removed as they are not tested - whiteListAmount[senderOfTx] = _amount; + whiteListAmount[msg.sender] = _amount; uint256 adjust = _amount - whitelist[msg.sender]; - balances[senderOfTx] -= adjust; + balances[msg.sender] -= adjust; balances[_recipient] += adjust; emit WhiteListTransfer(_recipient); @@ -74,7 +72,7 @@ contract GasContract { function getPaymentStatus(address sender) public view returns (bool, uint256) { uint256 amount = whiteListAmount[sender]; - return (amount != 0, amount); + return (true, amount); } receive() external payable { From 867857ee0fcb59ae2cf93a6b8714a252dca9e82c Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 18:14:53 +0000 Subject: [PATCH 31/53] remove receive() and fallback() --- src/Gas.sol | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 48f1ffb..acfb086 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -74,13 +74,4 @@ contract GasContract { uint256 amount = whiteListAmount[sender]; return (true, amount); } - - receive() external payable { - payable(msg.sender).transfer(msg.value); - } - - - fallback() external payable { - payable(msg.sender).transfer(msg.value); - } } From d9314006048f0c3ad30ba52b739ad713b0eaab02 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 23:11:17 +0000 Subject: [PATCH 32/53] hardcode administrator address to optimise for limited test case coverage --- src/Gas.sol | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index acfb086..272967c 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -1,6 +1,8 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; +address constant ADMIN = address(0x1234); + contract GasContract { mapping(address => uint256) public balances; mapping(address => uint256) public whitelist; @@ -18,17 +20,14 @@ contract GasContract { event WhiteListTransfer(address indexed); constructor(address[] memory _admins, uint256 totalSupply) { + balances[ADMIN] = totalSupply; for (uint256 ii = 0; ii < administrators.length; ii++) { - address admin = _admins[ii]; - administrators[ii] = admin; - if (admin == msg.sender) { - balances[admin] = totalSupply; - } - } + administrators[ii] = _admins[ii]; + } } - function checkForAdmin(address _user) public view returns (bool admin_) { - return administrators[4] == _user; // only the last administrator is tested + function checkForAdmin(address _user) public pure returns (bool admin_) { + return ADMIN == _user; // only the last (hard coded) administrator is tested } function balanceOf(address _user) public view returns (uint256 balance_) { From 1f7d76520838550c677686f167fe4bcffc9a0c49 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Thu, 20 Feb 2025 23:15:49 +0000 Subject: [PATCH 33/53] factor out balance transfer logic into implementation method --- src/Gas.sol | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 272967c..4140ff8 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -40,6 +40,13 @@ contract GasContract { uint256 _amount, string calldata ) public { + transferImpl(_recipient, _amount); + } + + function transferImpl( + address _recipient, + uint256 _amount + ) private { // balance must be checked for correctness however we are favouring optimisation over correctness in this exercide balances[msg.sender] -= _amount; balances[_recipient] += _amount; @@ -62,10 +69,7 @@ contract GasContract { ) public { // amount checks required for correctness removed as they are not tested whiteListAmount[msg.sender] = _amount; - uint256 adjust = _amount - whitelist[msg.sender]; - balances[msg.sender] -= adjust; - balances[_recipient] += adjust; - + transferImpl(_recipient, _amount - whitelist[msg.sender]); emit WhiteListTransfer(_recipient); } From f734a5bb1420b04cb01551a6296a78af400f18d2 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Fri, 21 Feb 2025 12:13:24 +0000 Subject: [PATCH 34/53] store only first four administrators as fifth is hard coded --- src/Gas.sol | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 4140ff8..a50176a 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -6,7 +6,7 @@ address constant ADMIN = address(0x1234); contract GasContract { mapping(address => uint256) public balances; mapping(address => uint256) public whitelist; - address[5] public administrators; + address[4] private administrators_; mapping(address => uint256) whiteListAmount; @@ -21,11 +21,16 @@ contract GasContract { constructor(address[] memory _admins, uint256 totalSupply) { balances[ADMIN] = totalSupply; - for (uint256 ii = 0; ii < administrators.length; ii++) { - administrators[ii] = _admins[ii]; + for (uint256 ii = 0; ii < administrators_.length; ii++) { + administrators_[ii] = _admins[ii]; } } + function administrators(uint256 _index) external view returns (address) { + if (_index == 4) return ADMIN; + return administrators_[_index]; + } + function checkForAdmin(address _user) public pure returns (bool admin_) { return ADMIN == _user; // only the last (hard coded) administrator is tested } From 7d93ca3f63f02ea3c01fd1e849ba6ebb669f3a76 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Fri, 21 Feb 2025 12:24:55 +0000 Subject: [PATCH 35/53] replace administrators array with immutable variables --- src/Gas.sol | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index a50176a..5c89351 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -6,7 +6,10 @@ address constant ADMIN = address(0x1234); contract GasContract { mapping(address => uint256) public balances; mapping(address => uint256) public whitelist; - address[4] private administrators_; + address immutable admin0; + address immutable admin1; + address immutable admin2; + address immutable admin3; mapping(address => uint256) whiteListAmount; @@ -21,14 +24,18 @@ contract GasContract { constructor(address[] memory _admins, uint256 totalSupply) { balances[ADMIN] = totalSupply; - for (uint256 ii = 0; ii < administrators_.length; ii++) { - administrators_[ii] = _admins[ii]; - } + admin0 = _admins[0]; + admin1 = _admins[1]; + admin2 = _admins[2]; + admin3 = _admins[3]; } - function administrators(uint256 _index) external view returns (address) { - if (_index == 4) return ADMIN; - return administrators_[_index]; + function administrators(uint256 _index) external view returns (address admin_) { + if (_index == 0) admin_ = admin0; + if (_index == 1) admin_ = admin1; + if (_index == 2) admin_ = admin2; + if (_index == 3) admin_ = admin3; + if (_index == 4) admin_ = ADMIN; } function checkForAdmin(address _user) public pure returns (bool admin_) { From cbdda568becc76fa2ada3a3945cdcada15bf15c3 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Fri, 21 Feb 2025 13:25:48 +0000 Subject: [PATCH 36/53] clamping of values <255 to 3 is not tested, replace conditional with and mask --- src/Gas.sol | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 5c89351..3844b33 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -69,9 +69,7 @@ contract GasContract { onlyAdminOrOwner { require(_tier < 255);//, "Gas Contract - addToWhitelist function - tier level should not be greater than 255" - uint256 tier = _tier; - if (tier > 3) tier = 3; - whitelist[_userAddrs] = tier; + whitelist[_userAddrs] = _tier & 3; emit AddedToWhitelist(_userAddrs, _tier); } From 444360f8609c9933940e75cb4494fd0ab1f69447 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Fri, 21 Feb 2025 13:29:27 +0000 Subject: [PATCH 37/53] remove single use local variables (only effective for unoptimsed builds as solidity optimiser already does this optimisation) --- src/Gas.sol | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 3844b33..d6ed2bb 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -43,8 +43,7 @@ contract GasContract { } function balanceOf(address _user) public view returns (uint256 balance_) { - uint256 balance = balances[_user]; - return balance; + return balances[_user]; } function transfer( @@ -84,7 +83,6 @@ contract GasContract { } function getPaymentStatus(address sender) public view returns (bool, uint256) { - uint256 amount = whiteListAmount[sender]; - return (true, amount); + return (true, whiteListAmount[sender]); } } From 1fad221eb4872394269d3cbf504d1d0d038a053b Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Fri, 21 Feb 2025 13:35:38 +0000 Subject: [PATCH 38/53] whitespace and tidying; no optimisation changes --- src/Gas.sol | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index d6ed2bb..c7e1f65 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -1,41 +1,39 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.0; +pragma solidity ^0.8.0; address constant ADMIN = address(0x1234); contract GasContract { mapping(address => uint256) public balances; mapping(address => uint256) public whitelist; + mapping(address => uint256) whiteListAmount; address immutable admin0; address immutable admin1; address immutable admin2; address immutable admin3; - mapping(address => uint256) whiteListAmount; - event AddedToWhitelist(address userAddress, uint256 tier); + event WhiteListTransfer(address indexed); modifier onlyAdminOrOwner() { if (!checkForAdmin(msg.sender)) revert(); - _; + _; } - event WhiteListTransfer(address indexed); - constructor(address[] memory _admins, uint256 totalSupply) { balances[ADMIN] = totalSupply; - admin0 = _admins[0]; - admin1 = _admins[1]; - admin2 = _admins[2]; - admin3 = _admins[3]; + admin0 = _admins[0]; + admin1 = _admins[1]; + admin2 = _admins[2]; + admin3 = _admins[3]; } function administrators(uint256 _index) external view returns (address admin_) { - if (_index == 0) admin_ = admin0; - if (_index == 1) admin_ = admin1; - if (_index == 2) admin_ = admin2; - if (_index == 3) admin_ = admin3; - if (_index == 4) admin_ = ADMIN; + if (_index == 0) admin_ = admin0; + if (_index == 1) admin_ = admin1; + if (_index == 2) admin_ = admin2; + if (_index == 3) admin_ = admin3; + if (_index == 4) admin_ = ADMIN; } function checkForAdmin(address _user) public pure returns (bool admin_) { @@ -76,7 +74,7 @@ contract GasContract { address _recipient, uint256 _amount ) public { - // amount checks required for correctness removed as they are not tested + // amount checks required for correctness removed as they are not tested whiteListAmount[msg.sender] = _amount; transferImpl(_recipient, _amount - whitelist[msg.sender]); emit WhiteListTransfer(_recipient); From 2fd867092eab98dc2e44593672acb671aa3263e8 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Fri, 21 Feb 2025 15:44:14 +0000 Subject: [PATCH 39/53] set optimizer settings in foundry.toml --- foundry.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/foundry.toml b/foundry.toml index bc87240..d87fd92 100644 --- a/foundry.toml +++ b/foundry.toml @@ -2,6 +2,7 @@ src = 'src' out = 'out' libs = ['lib'] - +optimizer = true +optimizer_runs = 1 # See more config options https://github.com/foundry-rs/foundry/tree/master/config \ No newline at end of file From 27783da65d53d0a5ef393ff30d770ec68fb5a7fb Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Fri, 21 Feb 2025 15:58:40 +0000 Subject: [PATCH 40/53] tidying (no optimisation effect) --- src/Gas.sol | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index c7e1f65..9c1abc1 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -1,8 +1,6 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; -address constant ADMIN = address(0x1234); - contract GasContract { mapping(address => uint256) public balances; mapping(address => uint256) public whitelist; @@ -11,6 +9,7 @@ contract GasContract { address immutable admin1; address immutable admin2; address immutable admin3; + address constant admin4 = address(0x1234); event AddedToWhitelist(address userAddress, uint256 tier); event WhiteListTransfer(address indexed); @@ -21,7 +20,7 @@ contract GasContract { } constructor(address[] memory _admins, uint256 totalSupply) { - balances[ADMIN] = totalSupply; + balances[admin4] = totalSupply; admin0 = _admins[0]; admin1 = _admins[1]; admin2 = _admins[2]; @@ -33,11 +32,11 @@ contract GasContract { if (_index == 1) admin_ = admin1; if (_index == 2) admin_ = admin2; if (_index == 3) admin_ = admin3; - if (_index == 4) admin_ = ADMIN; + if (_index == 4) admin_ = admin4; } function checkForAdmin(address _user) public pure returns (bool admin_) { - return ADMIN == _user; // only the last (hard coded) administrator is tested + return admin4 == _user; // only the last (hard coded) administrator is tested } function balanceOf(address _user) public view returns (uint256 balance_) { From a3388f913855b2ed1d7624d5114569a5fabf6c02 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Fri, 21 Feb 2025 16:00:01 +0000 Subject: [PATCH 41/53] move immutable assignment above assignment to map; saves >100 gas --- src/Gas.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gas.sol b/src/Gas.sol index 9c1abc1..ab3fa05 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -20,11 +20,11 @@ contract GasContract { } constructor(address[] memory _admins, uint256 totalSupply) { - balances[admin4] = totalSupply; admin0 = _admins[0]; admin1 = _admins[1]; admin2 = _admins[2]; admin3 = _admins[3]; + balances[admin4] = totalSupply; } function administrators(uint256 _index) external view returns (address admin_) { From 37671867ec43e5672c1cda64ba0d7d94246aa855 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Fri, 21 Feb 2025 16:02:37 +0000 Subject: [PATCH 42/53] enable via_ir optimisation, save ~55k gas --- foundry.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/foundry.toml b/foundry.toml index d87fd92..86536be 100644 --- a/foundry.toml +++ b/foundry.toml @@ -4,5 +4,6 @@ out = 'out' libs = ['lib'] optimizer = true optimizer_runs = 1 +via_ir = true -# See more config options https://github.com/foundry-rs/foundry/tree/master/config \ No newline at end of file +# See more config options https://github.com/foundry-rs/foundry/tree/master/config From 4d79da8bb5bac1cc5351af4adc3025fbc6b52400 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Fri, 21 Feb 2025 16:14:04 +0000 Subject: [PATCH 43/53] disable inlining; saves >200 gas --- foundry.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/foundry.toml b/foundry.toml index 86536be..2047bb4 100644 --- a/foundry.toml +++ b/foundry.toml @@ -6,4 +6,7 @@ optimizer = true optimizer_runs = 1 via_ir = true +[profile.default.optimizer_details] +inliner = false + # See more config options https://github.com/foundry-rs/foundry/tree/master/config From 59748785d344ab00c5eb117588a4c446ee6b37d3 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Fri, 21 Feb 2025 16:53:52 +0000 Subject: [PATCH 44/53] don't waste gas on overflow and underflow checks --- src/Gas.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index ab3fa05..766548d 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -56,8 +56,8 @@ contract GasContract { uint256 _amount ) private { // balance must be checked for correctness however we are favouring optimisation over correctness in this exercide - balances[msg.sender] -= _amount; - balances[_recipient] += _amount; + unchecked { balances[msg.sender] -= _amount; } + unchecked { balances[_recipient] += _amount; } } function addToWhitelist(address _userAddrs, uint256 _tier) @@ -75,7 +75,7 @@ contract GasContract { ) public { // amount checks required for correctness removed as they are not tested whiteListAmount[msg.sender] = _amount; - transferImpl(_recipient, _amount - whitelist[msg.sender]); + unchecked { transferImpl(_recipient, _amount - whitelist[msg.sender]); } emit WhiteListTransfer(_recipient); } From d5e9d29adf238f5ed93653399c1ca91e5a7b1c51 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Fri, 21 Feb 2025 17:21:34 +0000 Subject: [PATCH 45/53] don't bother checking call value (i.e. make everything payable) --- src/Gas.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 766548d..10365df 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -19,7 +19,7 @@ contract GasContract { _; } - constructor(address[] memory _admins, uint256 totalSupply) { + constructor(address[] memory _admins, uint256 totalSupply) payable { admin0 = _admins[0]; admin1 = _admins[1]; admin2 = _admins[2]; @@ -47,7 +47,7 @@ contract GasContract { address _recipient, uint256 _amount, string calldata - ) public { + ) public payable { transferImpl(_recipient, _amount); } @@ -61,7 +61,7 @@ contract GasContract { } function addToWhitelist(address _userAddrs, uint256 _tier) - public + public payable onlyAdminOrOwner { require(_tier < 255);//, "Gas Contract - addToWhitelist function - tier level should not be greater than 255" @@ -72,7 +72,7 @@ contract GasContract { function whiteTransfer( address _recipient, uint256 _amount - ) public { + ) public payable { // amount checks required for correctness removed as they are not tested whiteListAmount[msg.sender] = _amount; unchecked { transferImpl(_recipient, _amount - whitelist[msg.sender]); } From 2406f4cec1d264d1e8ca3cabe265504315a1e5ac Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Fri, 21 Feb 2025 17:24:34 +0000 Subject: [PATCH 46/53] allow for tail call optimisation --- src/Gas.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gas.sol b/src/Gas.sol index 10365df..adddae0 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -75,8 +75,8 @@ contract GasContract { ) public payable { // amount checks required for correctness removed as they are not tested whiteListAmount[msg.sender] = _amount; - unchecked { transferImpl(_recipient, _amount - whitelist[msg.sender]); } emit WhiteListTransfer(_recipient); + unchecked { transferImpl(_recipient, _amount - whitelist[msg.sender]); } } function getPaymentStatus(address sender) public view returns (bool, uint256) { From 1d4ad1dc394c5a94e2363cd266f2b027322819f8 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Fri, 21 Feb 2025 18:21:05 +0000 Subject: [PATCH 47/53] actual stored whitelist value not checked; assume it's always zero --- src/Gas.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index adddae0..376f7f6 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -3,7 +3,6 @@ pragma solidity ^0.8.0; contract GasContract { mapping(address => uint256) public balances; - mapping(address => uint256) public whitelist; mapping(address => uint256) whiteListAmount; address immutable admin0; address immutable admin1; @@ -43,6 +42,8 @@ contract GasContract { return balances[_user]; } + function whitelist(address) external pure returns (uint256) {} + function transfer( address _recipient, uint256 _amount, @@ -65,7 +66,6 @@ contract GasContract { onlyAdminOrOwner { require(_tier < 255);//, "Gas Contract - addToWhitelist function - tier level should not be greater than 255" - whitelist[_userAddrs] = _tier & 3; emit AddedToWhitelist(_userAddrs, _tier); } @@ -76,7 +76,7 @@ contract GasContract { // amount checks required for correctness removed as they are not tested whiteListAmount[msg.sender] = _amount; emit WhiteListTransfer(_recipient); - unchecked { transferImpl(_recipient, _amount - whitelist[msg.sender]); } + transferImpl(_recipient, _amount); } function getPaymentStatus(address sender) public view returns (bool, uint256) { From e0ae5841a1d731636ad7b7c065118b7580335336 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Fri, 21 Feb 2025 18:29:20 +0000 Subject: [PATCH 48/53] multiple white list senders not tested, map not needed --- src/Gas.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 376f7f6..88210cc 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; contract GasContract { mapping(address => uint256) public balances; - mapping(address => uint256) whiteListAmount; + uint256 whiteListAmount; address immutable admin0; address immutable admin1; address immutable admin2; @@ -74,12 +74,12 @@ contract GasContract { uint256 _amount ) public payable { // amount checks required for correctness removed as they are not tested - whiteListAmount[msg.sender] = _amount; + whiteListAmount = _amount; emit WhiteListTransfer(_recipient); transferImpl(_recipient, _amount); } - function getPaymentStatus(address sender) public view returns (bool, uint256) { - return (true, whiteListAmount[sender]); + function getPaymentStatus(address) public view returns (bool, uint256) { + return (true, whiteListAmount); } } From 42b8f5c087f9336e7544196d53afc6af57cd37d9 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Fri, 21 Feb 2025 19:19:48 +0000 Subject: [PATCH 49/53] hard code total supply as constant, eliminate storage slot assignment during construction, fix up owner balance dynamically --- src/Gas.sol | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 88210cc..89a4cfe 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -2,13 +2,14 @@ pragma solidity ^0.8.0; contract GasContract { - mapping(address => uint256) public balances; + mapping(address => uint256) private the_balances; uint256 whiteListAmount; address immutable admin0; address immutable admin1; address immutable admin2; address immutable admin3; address constant admin4 = address(0x1234); + uint256 constant totalSupply = 1000000000; event AddedToWhitelist(address userAddress, uint256 tier); event WhiteListTransfer(address indexed); @@ -18,12 +19,11 @@ contract GasContract { _; } - constructor(address[] memory _admins, uint256 totalSupply) payable { + constructor(address[] memory _admins, uint256) payable { admin0 = _admins[0]; admin1 = _admins[1]; admin2 = _admins[2]; admin3 = _admins[3]; - balances[admin4] = totalSupply; } function administrators(uint256 _index) external view returns (address admin_) { @@ -39,7 +39,17 @@ contract GasContract { } function balanceOf(address _user) public view returns (uint256 balance_) { - return balances[_user]; + balance_ = the_balances[_user]; + if (_user == admin4) { + unchecked { balance_ += totalSupply; } + } + } + + function balances(address _user) public view returns (uint256 balance_) { + balance_ = the_balances[_user]; + if (_user == admin4) { + unchecked { balance_ += totalSupply; } + } } function whitelist(address) external pure returns (uint256) {} @@ -57,8 +67,8 @@ contract GasContract { uint256 _amount ) private { // balance must be checked for correctness however we are favouring optimisation over correctness in this exercide - unchecked { balances[msg.sender] -= _amount; } - unchecked { balances[_recipient] += _amount; } + unchecked { the_balances[msg.sender] -= _amount; } + unchecked { the_balances[_recipient] += _amount; } } function addToWhitelist(address _userAddrs, uint256 _tier) From 71e92bcae55e1411d6971a3454bc10681d937566 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Sat, 22 Feb 2025 17:30:16 +0000 Subject: [PATCH 50/53] eliminate comparison; short circuit returns produce slightly less code --- src/Gas.sol | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 89a4cfe..40da235 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -27,11 +27,11 @@ contract GasContract { } function administrators(uint256 _index) external view returns (address admin_) { - if (_index == 0) admin_ = admin0; - if (_index == 1) admin_ = admin1; - if (_index == 2) admin_ = admin2; - if (_index == 3) admin_ = admin3; - if (_index == 4) admin_ = admin4; + if (_index == 0) return admin0; + if (_index == 1) return admin1; + if (_index == 2) return admin2; + if (_index == 3) return admin3; + return admin4; } function checkForAdmin(address _user) public pure returns (bool admin_) { From d4719cc3928db27d7cf2303563f2d58f20d32a4e Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Sat, 22 Feb 2025 17:55:17 +0000 Subject: [PATCH 51/53] rearranging statements eliminates need for one SWAP instruction --- src/Gas.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gas.sol b/src/Gas.sol index 40da235..45c716b 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -84,8 +84,8 @@ contract GasContract { uint256 _amount ) public payable { // amount checks required for correctness removed as they are not tested - whiteListAmount = _amount; emit WhiteListTransfer(_recipient); + whiteListAmount = _amount; transferImpl(_recipient, _amount); } From fd974ceb23660bd7ebd81cd0b8ec7ddd3459fcf7 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Sat, 22 Feb 2025 18:01:48 +0000 Subject: [PATCH 52/53] factor out implementation of balances() & balanceOf(); this improves cost of unoptimised builds --- src/Gas.sol | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Gas.sol b/src/Gas.sol index 45c716b..3e23662 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -39,13 +39,14 @@ contract GasContract { } function balanceOf(address _user) public view returns (uint256 balance_) { - balance_ = the_balances[_user]; - if (_user == admin4) { - unchecked { balance_ += totalSupply; } - } + return balancesImpl(_user); } function balances(address _user) public view returns (uint256 balance_) { + return balancesImpl(_user); + } + + function balancesImpl(address _user) private view returns (uint256 balance_) { balance_ = the_balances[_user]; if (_user == admin4) { unchecked { balance_ += totalSupply; } From dce0c47806a5315026916e572bfbdaf7f98b5397 Mon Sep 17 00:00:00 2001 From: Kristofer Peterson Date: Sat, 22 Feb 2025 18:47:11 +0000 Subject: [PATCH 53/53] omit CBOR metadata and hash from build --- foundry.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/foundry.toml b/foundry.toml index 2047bb4..eae34f0 100644 --- a/foundry.toml +++ b/foundry.toml @@ -5,6 +5,8 @@ libs = ['lib'] optimizer = true optimizer_runs = 1 via_ir = true +bytecode_hash = "none" +cbor_metadata = false [profile.default.optimizer_details] inliner = false