From fd621c0f6e2100941c7775dd34208c6b3e0d7d72 Mon Sep 17 00:00:00 2001 From: "Quatre.Finance" <35783747+bobeu@users.noreply.github.com> Date: Sun, 7 May 2023 18:07:16 +0100 Subject: [PATCH 1/3] Optimized Gas.sol in src/optimized folder --- src/Gas.sol | 2 +- src/optimized/Gas.sol | 209 +++++++++++++++++++++++++++++++++ src/optimized/IGasContract.sol | 60 ++++++++++ 3 files changed, 270 insertions(+), 1 deletion(-) create mode 100644 src/optimized/Gas.sol create mode 100644 src/optimized/IGasContract.sol diff --git a/src/Gas.sol b/src/Gas.sol index aa95425..6ee544e 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -6,7 +6,7 @@ import "./Ownable.sol"; contract Constants { uint256 public tradeFlag = 1; uint256 public basicFlag = 0; - uint256 public dividendFlag = 1; + uint256 public dividendFlag = 1; } contract GasContract is Ownable, Constants { diff --git a/src/optimized/Gas.sol b/src/optimized/Gas.sol new file mode 100644 index 0000000..0ac9028 --- /dev/null +++ b/src/optimized/Gas.sol @@ -0,0 +1,209 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.0; + +import "./Ownable.sol"; +import "./IGasContract.sol"; + +contract Constants { + uint256 public tradeFlag = 1; + uint256 public basicFlag = 0; + uint256 public dividendFlag = 1; +} + +contract GasContract is IGasContract, Ownable, Constants { + uint256 public totalSupply; + uint256 public paymentCounter; + + mapping(address => Payment[]) public payments; + mapping(address => uint256) whitelist; + mapping(address => uint256) public balances; + mapping(address => ImportantStruct) public whiteListStruct; + + // Sorted + mapping (address => bool) private isAdmin; + + PaymentType constant defaultPayment = PaymentType.Unknown; + + History[] public paymentHistory; + + modifier compareBalance(address _user, uint _amount) { + uint balance_ = balances[senderOfTx]; + if(balance_ < _amount) { revert InsufficientBalance(balance_) }; + _; + } + + constructor(address[] memory _admins, uint256 _totalSupply) { + contractOwner = _msgSender(); + totalSupply = _totalSupply; + balances[contractOwner] = totalSupply; + wasLastOdd = 1; + + for (uint256 ii = 0; ii < administrators.length; ii++) { + address currentAddr = _admins[ii]; + if (currentAddr != address(0)) { + isAdmin[currentAddr] = true; + } + } + emit supplyChanged(contractOwner, totalSupply); + } + + receive() external payable { + revert(); + } + + + fallback() external payable { + revert(); + } + + function _onlyAdminOrOwner() internal returns(address senderOfTx) { + senderOfTx = _msgSender(); + require(_user == owner() || _checkForAdmin(senderOfTx), "Access denied"); + return senderOfTx; + } + + function _checkIfWhiteListed() internal { + uint256 usersTier = whitelist[_msgSender()]; + require(usersTier > 0 && userTier < 4, "GC: Not whitelisted"); + } + + function getPaymentHistory() + public + payable + returns (History[] memory paymentHistory_) + { + return paymentHistory; + } + + /// @dev Function activates or deactivates admin + function setAdmin(address _user, bool _status) public onlyOwner { + bool _isAdmin = isAdmin[_user]; + if(!_isAdmin) { + if(!_status) revert TargetAlreadyAnAdmin(_user); + } else { + if(_status) revert TargetAlreadyDeactivated(_user); + } + isAdmin[_user] = _status; + } + + function _checkForAdmin(address _user) public view returns (bool admin_) { + _admin = isAdmin[_user]; + } + + function balanceOf(address _user) public view returns (uint256 balance_) { + balance_ = balances[_user]; + return balance_; + } + + function getTradingMode() public view returns (bool) { + if (tradeFlag == 1 || dividendFlag == 1) { + return true; + } + return false; + } + + function addHistory(address _updateAddress, bool _tradeMode) public + { + paymentHistory.push(History(block.timestamp, _updateAddress, block.number)); + } + + function getPayments(address _user) + public + view + returns (Payment[] memory) + { + if(_user == address(0)) revert InvalidAddress(); + return payments[_user]; + } + + function transfer( + address _recipient, + uint256 _amount, + string calldata _name + ) public compareBalance(_recipient, _amount) returns (bool) { + address senderOfTx = _msgSender(); + uint balance_ = balances[senderOfTx]; + uint nameLen = bytes(_name).length; + if(nameLen > 8) revert MaxNameLengthExceeded(nameLen); + + balances[senderOfTx] = balance_ - _amount; + balances[_recipient] += _amount; + + emit Transfer(_recipient, _amount); + payments[senderOfTx].push( + Payment( + PaymentType.BasicPayment, + _getPaymentCounter(), + false, + _name, + _recipient, + address(0), + _amount + ) + ); + + return true; + } + + function _getPaymentCounter() internal returns(uint counter) { + paymentCounter ++; + counter = paymentCounter; + } + + function updatePayment( + address _user, + uint256 _ID, + uint256 _amount, + PaymentType _type + ) public { + address senderOfTx = _onlyAdminOrOwner(); + if(amount == 0) revert AmountShouldBeGreaterThanZero(); + if(_user == address(0)) revert InvalidAddress(_user); + + require(payments[_user].length > _ID, "Invalid ID"); + payments[_user][_ID].adminUpdated = true; + payments[_user][_ID].admin = _user; + payments[_user][_ID].paymentType = _type; + payments[_user][_ID].amount = _amount; + bool tradingMode = getTradingMode(); + addHistory(_user, tradingMode); + emit PaymentUpdated( + senderOfTx, + _ID, + _amount, + payments[_user][_ID].recipientName + ); + } + + function addToWhitelist(address _userAddrs, uint256 _tier) public + { + _onlyAdminOrOwner(); + if(tier > type(uint8).max) revert LevelExceedBoundry(_tier); + whitelist[_userAddrs] = _tier; + + emit AddedToWhitelist(_userAddrs, _tier); + } + + function whiteTransfer( + address _recipient, + uint256 _amount + ) public compareBalance(_recipient, _amount) { + _checkIfWhiteListed(); + address senderOfTx = _msgSender(); + whiteListStruct[senderOfTx] = ImportantStruct(_amount, 0, 0, 0, true, senderOfTx); + if(_amount <= 3) revert AmountShouldBeAbove3(_amount); + uint w_balanceSender = whitelist[senderOfTx]; + uint w_balanceRecipient = whitelist[recipient]; + balances[senderOfTx] -= _amount; + balances[_recipient] += _amount; + balances[senderOfTx] += w_balanceSender + balances[_recipient] -= w_balanceRecipient; + + emit WhiteListTransfer(_recipient); + } + + + function getPaymentStatus(address sender) public returns (bool, uint256) { + return (whiteListStruct[sender].paymentStatus, whiteListStruct[sender].amount); + } +} \ No newline at end of file diff --git a/src/optimized/IGasContract.sol b/src/optimized/IGasContract.sol new file mode 100644 index 0000000..043b18f --- /dev/null +++ b/src/optimized/IGasContract.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: UNLICENSED + +pragma solidity 0.8.0; + +interface IGasContract { + event AddedToWhitelist(address userAddress, uint256 tier); + 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); + + error InvalidAddress(); + error NotAnAdmin(address); + error LevelExceedBoundry(uint256); + error InsufficientBalance(uint256); + error TargetAlreadyAnAdmin(address); + error MaxNameLengthExceeded(uint256); + error AmountShouldBeAbove3(uint256); + error AmountShouldBeGreaterThanZero(); + error TargetAlreadyDeactivated(address); + + enum PaymentType { + Unknown, + BasicPayment, + Refund, + Dividend, + GroupPayment + } + + struct Payment { + PaymentType paymentType; + uint256 paymentID; + bool adminUpdated; + string recipientName; // max 8 characters + address recipient; + address admin; // administrators address + uint256 amount; + } + + struct History { + uint256 lastUpdate; + address updatedBy; + uint256 blockNumber; + } + + struct ImportantStruct { + uint256 amount; + uint256 valueA; // max 3 digits + uint256 bigValue; + uint256 valueB; // max 3 digits + bool paymentStatus; + address sender; + } + +} \ No newline at end of file From f56af7dc420b1aff63f45883eae4e7f661448310 Mon Sep 17 00:00:00 2001 From: "Quatre.Finance" <35783747+bobeu@users.noreply.github.com> Date: Mon, 8 May 2023 16:40:43 +0100 Subject: [PATCH 2/3] Updated --- foundry.toml | 3 + src/Gas.sol | 257 +++++++++------------------ src/{optimized => }/IGasContract.sol | 22 +-- src/Ownable.sol | 2 +- src/optimized/Gas.sol | 209 ---------------------- test/Gas.UnitTests.t.sol | 2 +- 6 files changed, 97 insertions(+), 398 deletions(-) rename src/{optimized => }/IGasContract.sol (98%) delete mode 100644 src/optimized/Gas.sol diff --git a/foundry.toml b/foundry.toml index bc87240..9d74069 100644 --- a/foundry.toml +++ b/foundry.toml @@ -1,7 +1,10 @@ [profile.default] src = 'src' out = 'out' +solc = "0.8.18" libs = ['lib'] +optimizer = true +optimizerRun = 200 # See more config options https://github.com/foundry-rs/foundry/tree/master/config \ No newline at end of file diff --git a/src/Gas.sol b/src/Gas.sol index 6ee544e..873996e 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -1,5 +1,5 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.0; +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; import "./Ownable.sol"; @@ -10,42 +10,23 @@ contract Constants { } contract GasContract is Ownable, Constants { + error OnlyAdminOrOwner(); + error InvalidTier(uint8); + error Anomally(); + error InsufficientBalance(); + error ZeroAddress(); + error NameTooLong(); + error AmountShouldExceed3(); + uint256 public totalSupply = 0; // cannot be updated uint256 public paymentCounter = 0; 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, - Refund, - Dividend, - GroupPayment - } - PaymentType constant defaultPayment = PaymentType.Unknown; - - History[] public paymentHistory; // when a payment was updated - - struct Payment { - PaymentType paymentType; - uint256 paymentID; - bool adminUpdated; - string recipientName; // max 8 characters - address recipient; - address admin; // administrators address - uint256 amount; - } - - struct History { - uint256 lastUpdate; - address updatedBy; - uint256 blockNumber; - } uint256 wasLastOdd = 1; mapping(address => uint256) public isOddWhitelistUser; @@ -61,37 +42,17 @@ contract GasContract is Ownable, Constants { 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" - ); - } + function onlyAdminOrOwner() internal view { + address senderOfTx = _msgSender(); + require(checkForAdmin(senderOfTx) || senderOfTx == contractOwner, "Denied"); } 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" - ); + address senderOfTx = _msgSender(); 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" + senderOfTx == sender && usersTier > 0 && usersTier < 4, + "Not whiteListed" ); _; } @@ -107,7 +68,7 @@ contract GasContract is Ownable, Constants { event WhiteListTransfer(address indexed); constructor(address[] memory _admins, uint256 _totalSupply) { - contractOwner = msg.sender; + contractOwner = _msgSender(); totalSupply = _totalSupply; for (uint256 ii = 0; ii < administrators.length; ii++) { @@ -127,14 +88,6 @@ contract GasContract is Ownable, Constants { } } - 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++) { @@ -160,116 +113,70 @@ contract GasContract is Ownable, Constants { return mode; } - - 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 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, 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" - ); + address senderOfTx = _msgSender(); + if(balances[senderOfTx] < _amount) revert InsufficientBalance(); + if(bytes(_name).length >= 9) revert NameTooLong(); + balances[senderOfTx] -= _amount; balances[_recipient] += _amount; emit Transfer(_recipient, _amount); - Payment memory payment; - payment.admin = address(0); - payment.adminUpdated = false; - payment.paymentType = PaymentType.BasicPayment; - payment.recipient = _recipient; - payment.amount = _amount; - 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); - } - - 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 - ); - } - } - } + return 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 = _msgSender(); + + // 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 { - require( - _tier < 255, - "Gas Contract - addToWhitelist function - tier level should not be greater than 255" - ); + onlyAdminOrOwner(); + if(_tier >= type(uint8).max) revert InvalidTier(uint8(_tier)); whitelist[_userAddrs] = _tier; + // if(_tier ) + if (_tier > 3) { whitelist[_userAddrs] -= _tier; whitelist[_userAddrs] = 3; @@ -288,7 +195,7 @@ contract GasContract is Ownable, Constants { wasLastOdd = 1; isOddWhitelistUser[_userAddrs] = wasLastAddedOdd; } else { - revert("Contract hacked, imposible, call help"); + revert Anomally(); } emit AddedToWhitelist(_userAddrs, _tier); } @@ -296,18 +203,13 @@ contract GasContract is Ownable, Constants { function whiteTransfer( address _recipient, uint256 _amount - ) public checkIfWhiteListed(msg.sender) { - address senderOfTx = msg.sender; - whiteListStruct[senderOfTx] = ImportantStruct(_amount, 0, 0, 0, true, msg.sender); + ) public checkIfWhiteListed(_msgSender()) { + address senderOfTx = _msgSender(); + whiteListStruct[senderOfTx] = ImportantStruct(_amount, 0, 0, 0, true, _msgSender()); - 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" - ); + if(balances[senderOfTx] < _amount) revert InsufficientBalance(); + if(_amount <= 3) revert AmountShouldExceed3(); + balances[senderOfTx] -= _amount; balances[_recipient] += _amount; balances[senderOfTx] += whitelist[senderOfTx]; @@ -317,16 +219,19 @@ contract GasContract is Ownable, Constants { } - function getPaymentStatus(address sender) public returns (bool, uint256) { + function getPaymentStatus(address sender) public view returns (bool, uint256) { return (whiteListStruct[sender].paymentStatus, whiteListStruct[sender].amount); } receive() external payable { - payable(msg.sender).transfer(msg.value); + payable(_msgSender()).transfer(msg.value); } fallback() external payable { - payable(msg.sender).transfer(msg.value); + payable(_msgSender()).transfer(msg.value); } -} \ No newline at end of file +} + + + diff --git a/src/optimized/IGasContract.sol b/src/IGasContract.sol similarity index 98% rename from src/optimized/IGasContract.sol rename to src/IGasContract.sol index 043b18f..5fdcdaf 100644 --- a/src/optimized/IGasContract.sol +++ b/src/IGasContract.sol @@ -1,8 +1,18 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.0; +pragma solidity 0.8.18; interface IGasContract { + error InvalidAddress(); + error NotAnAdmin(address); + error LevelExceedBoundry(uint256); + error InsufficientBalance(uint256); + error TargetAlreadyAnAdmin(address); + error MaxNameLengthExceeded(uint256); + error AmountShouldBeAbove3(uint256); + error AmountShouldBeGreaterThanZero(); + error TargetAlreadyDeactivated(address); + event AddedToWhitelist(address userAddress, uint256 tier); event supplyChanged(address indexed, uint256 indexed); event Transfer(address recipient, uint256 amount); @@ -14,16 +24,6 @@ interface IGasContract { ); event WhiteListTransfer(address indexed); - error InvalidAddress(); - error NotAnAdmin(address); - error LevelExceedBoundry(uint256); - error InsufficientBalance(uint256); - error TargetAlreadyAnAdmin(address); - error MaxNameLengthExceeded(uint256); - error AmountShouldBeAbove3(uint256); - error AmountShouldBeGreaterThanZero(); - error TargetAlreadyDeactivated(address); - enum PaymentType { Unknown, BasicPayment, diff --git a/src/Ownable.sol b/src/Ownable.sol index a8736c8..7a42b3d 100644 --- a/src/Ownable.sol +++ b/src/Ownable.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.0; +pragma solidity 0.8.18; /** * @dev Provides information about the current execution context, including the diff --git a/src/optimized/Gas.sol b/src/optimized/Gas.sol deleted file mode 100644 index 0ac9028..0000000 --- a/src/optimized/Gas.sol +++ /dev/null @@ -1,209 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.0; - -import "./Ownable.sol"; -import "./IGasContract.sol"; - -contract Constants { - uint256 public tradeFlag = 1; - uint256 public basicFlag = 0; - uint256 public dividendFlag = 1; -} - -contract GasContract is IGasContract, Ownable, Constants { - uint256 public totalSupply; - uint256 public paymentCounter; - - mapping(address => Payment[]) public payments; - mapping(address => uint256) whitelist; - mapping(address => uint256) public balances; - mapping(address => ImportantStruct) public whiteListStruct; - - // Sorted - mapping (address => bool) private isAdmin; - - PaymentType constant defaultPayment = PaymentType.Unknown; - - History[] public paymentHistory; - - modifier compareBalance(address _user, uint _amount) { - uint balance_ = balances[senderOfTx]; - if(balance_ < _amount) { revert InsufficientBalance(balance_) }; - _; - } - - constructor(address[] memory _admins, uint256 _totalSupply) { - contractOwner = _msgSender(); - totalSupply = _totalSupply; - balances[contractOwner] = totalSupply; - wasLastOdd = 1; - - for (uint256 ii = 0; ii < administrators.length; ii++) { - address currentAddr = _admins[ii]; - if (currentAddr != address(0)) { - isAdmin[currentAddr] = true; - } - } - emit supplyChanged(contractOwner, totalSupply); - } - - receive() external payable { - revert(); - } - - - fallback() external payable { - revert(); - } - - function _onlyAdminOrOwner() internal returns(address senderOfTx) { - senderOfTx = _msgSender(); - require(_user == owner() || _checkForAdmin(senderOfTx), "Access denied"); - return senderOfTx; - } - - function _checkIfWhiteListed() internal { - uint256 usersTier = whitelist[_msgSender()]; - require(usersTier > 0 && userTier < 4, "GC: Not whitelisted"); - } - - function getPaymentHistory() - public - payable - returns (History[] memory paymentHistory_) - { - return paymentHistory; - } - - /// @dev Function activates or deactivates admin - function setAdmin(address _user, bool _status) public onlyOwner { - bool _isAdmin = isAdmin[_user]; - if(!_isAdmin) { - if(!_status) revert TargetAlreadyAnAdmin(_user); - } else { - if(_status) revert TargetAlreadyDeactivated(_user); - } - isAdmin[_user] = _status; - } - - function _checkForAdmin(address _user) public view returns (bool admin_) { - _admin = isAdmin[_user]; - } - - function balanceOf(address _user) public view returns (uint256 balance_) { - balance_ = balances[_user]; - return balance_; - } - - function getTradingMode() public view returns (bool) { - if (tradeFlag == 1 || dividendFlag == 1) { - return true; - } - return false; - } - - function addHistory(address _updateAddress, bool _tradeMode) public - { - paymentHistory.push(History(block.timestamp, _updateAddress, block.number)); - } - - function getPayments(address _user) - public - view - returns (Payment[] memory) - { - if(_user == address(0)) revert InvalidAddress(); - return payments[_user]; - } - - function transfer( - address _recipient, - uint256 _amount, - string calldata _name - ) public compareBalance(_recipient, _amount) returns (bool) { - address senderOfTx = _msgSender(); - uint balance_ = balances[senderOfTx]; - uint nameLen = bytes(_name).length; - if(nameLen > 8) revert MaxNameLengthExceeded(nameLen); - - balances[senderOfTx] = balance_ - _amount; - balances[_recipient] += _amount; - - emit Transfer(_recipient, _amount); - payments[senderOfTx].push( - Payment( - PaymentType.BasicPayment, - _getPaymentCounter(), - false, - _name, - _recipient, - address(0), - _amount - ) - ); - - return true; - } - - function _getPaymentCounter() internal returns(uint counter) { - paymentCounter ++; - counter = paymentCounter; - } - - function updatePayment( - address _user, - uint256 _ID, - uint256 _amount, - PaymentType _type - ) public { - address senderOfTx = _onlyAdminOrOwner(); - if(amount == 0) revert AmountShouldBeGreaterThanZero(); - if(_user == address(0)) revert InvalidAddress(_user); - - require(payments[_user].length > _ID, "Invalid ID"); - payments[_user][_ID].adminUpdated = true; - payments[_user][_ID].admin = _user; - payments[_user][_ID].paymentType = _type; - payments[_user][_ID].amount = _amount; - bool tradingMode = getTradingMode(); - addHistory(_user, tradingMode); - emit PaymentUpdated( - senderOfTx, - _ID, - _amount, - payments[_user][_ID].recipientName - ); - } - - function addToWhitelist(address _userAddrs, uint256 _tier) public - { - _onlyAdminOrOwner(); - if(tier > type(uint8).max) revert LevelExceedBoundry(_tier); - whitelist[_userAddrs] = _tier; - - emit AddedToWhitelist(_userAddrs, _tier); - } - - function whiteTransfer( - address _recipient, - uint256 _amount - ) public compareBalance(_recipient, _amount) { - _checkIfWhiteListed(); - address senderOfTx = _msgSender(); - whiteListStruct[senderOfTx] = ImportantStruct(_amount, 0, 0, 0, true, senderOfTx); - if(_amount <= 3) revert AmountShouldBeAbove3(_amount); - uint w_balanceSender = whitelist[senderOfTx]; - uint w_balanceRecipient = whitelist[recipient]; - balances[senderOfTx] -= _amount; - balances[_recipient] += _amount; - balances[senderOfTx] += w_balanceSender - balances[_recipient] -= w_balanceRecipient; - - emit WhiteListTransfer(_recipient); - } - - - function getPaymentStatus(address sender) public returns (bool, uint256) { - return (whiteListStruct[sender].paymentStatus, whiteListStruct[sender].amount); - } -} \ No newline at end of file diff --git a/test/Gas.UnitTests.t.sol b/test/Gas.UnitTests.t.sol index 3ee8423..af2ebcc 100644 --- a/test/Gas.UnitTests.t.sol +++ b/test/Gas.UnitTests.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.0; +pragma solidity 0.8.18; import "forge-std/Test.sol"; import "../../src/Gas.sol"; From 5c31e1779edb5ba314c4062a718242bda019b9ba Mon Sep 17 00:00:00 2001 From: "Quatre.Finance" <35783747+bobeu@users.noreply.github.com> Date: Mon, 8 May 2023 17:19:08 +0100 Subject: [PATCH 3/3] Improved the gas by 2000 --- src/Gas.sol | 318 +++++++++++++++++++++---------------------- src/IGasContract.sol | 60 -------- 2 files changed, 157 insertions(+), 221 deletions(-) delete mode 100644 src/IGasContract.sol diff --git a/src/Gas.sol b/src/Gas.sol index 873996e..6167876 100644 --- a/src/Gas.sol +++ b/src/Gas.sol @@ -1,201 +1,196 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.18; -import "./Ownable.sol"; - -contract Constants { - uint256 public tradeFlag = 1; - uint256 public basicFlag = 0; - uint256 public dividendFlag = 1; -} - -contract GasContract is Ownable, Constants { - error OnlyAdminOrOwner(); - error InvalidTier(uint8); - error Anomally(); - error InsufficientBalance(); - error ZeroAddress(); - error NameTooLong(); - error AmountShouldExceed3(); - - uint256 public totalSupply = 0; // cannot be updated - uint256 public paymentCounter = 0; + +contract GasContract { + uint256 totalSupply; // cannot be updated + uint256 paymentCounter; mapping(address => uint256) public balances; - uint256 public tradePercent = 12; - address public contractOwner; - uint256 public tradeMode = 0; + address contractOwner; + // mapping(address => Payment[]) public payments; mapping(address => uint256) public whitelist; address[5] public administrators; - bool public isReady = false; - uint256 wasLastOdd = 1; - mapping(address => uint256) public isOddWhitelistUser; + bool isReady ; +/** + enum PaymentType { + Unknown, + BasicPayment + } +*/ + // History[] paymentHistory; // when a payment was updated + struct ImportantStruct { uint256 amount; - uint256 valueA; // max 3 digits - uint256 bigValue; - uint256 valueB; // max 3 digits bool paymentStatus; - address sender; } + + // struct Payment { + // uint256 paymentID; + // bool adminUpdated; + // string recipientName; // max 8 characters + // address recipient; + // address admin; // administrators address + // uint256 amount; + // } + + // struct History { + // uint256 lastUpdate; + // address updatedBy; + // uint256 blockNumber; + // } + + + + mapping(address => ImportantStruct) public whiteListStruct; + error SthWrong(); + event AddedToWhitelist(address userAddress, uint256 tier); - function onlyAdminOrOwner() internal view { - address senderOfTx = _msgSender(); - require(checkForAdmin(senderOfTx) || senderOfTx == contractOwner, "Denied"); - } - modifier checkIfWhiteListed(address sender) { - address senderOfTx = _msgSender(); - uint256 usersTier = whitelist[senderOfTx]; - require( - senderOfTx == sender && usersTier > 0 && usersTier < 4, - "Not whiteListed" - ); - _; - } event supplyChanged(address indexed, uint256 indexed); event Transfer(address recipient, uint256 amount); - event PaymentUpdated( - address admin, - uint256 ID, - uint256 amount, - string recipient - ); + // event PaymentUpdated( + // address admin, + // uint256 ID, + // uint256 amount, + // string recipient + // ); event WhiteListTransfer(address indexed); constructor(address[] memory _admins, uint256 _totalSupply) { - contractOwner = _msgSender(); + contractOwner = msg.sender; totalSupply = _totalSupply; - for (uint256 ii = 0; ii < administrators.length; ii++) { + unchecked { + + for (uint256 ii = 0; ii < 5; ++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) { + } else { + balances[_admins[ii]]; emit supplyChanged(_admins[ii], 0); } } } + } } - 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; + function onlyAdminOrOwner(address sndr) internal view { + if (contractOwner != sndr || !checkForAdmin(sndr)) { + revert SthWrong(); + } + } - function balanceOf(address _user) public view returns (uint256 balance_) { - uint256 balance = balances[_user]; - return balance; +/** + function getPaymentHistory() + external + payable + returns (History[] memory paymentHistory_) + { + return paymentHistory; } - function getTradingMode() public view returns (bool mode_) { - bool mode = false; - if (tradeFlag == 1 || dividendFlag == 1) { - mode = true; - } else { - mode = false; +*/ + + function checkForAdmin(address _user) internal view returns (bool admin_) { + unchecked { + for (uint256 ii = 0; ii < 5; ++ii) { + if (administrators[ii] == _user) { + admin_ = true; + } + } } - return mode; + return admin_; + } + + function balanceOf(address _user) external view returns (uint256 balance_) { + balance_ = balances[_user]; + } +/** + function getPayments(address _user) + internal + view + returns (Payment[] memory payments_) + { + return payments[_user]; + } +*/ function transfer( address _recipient, uint256 _amount, string calldata _name - ) public returns (bool status_) { - address senderOfTx = _msgSender(); - if(balances[senderOfTx] < _amount) revert InsufficientBalance(); - if(bytes(_name).length >= 9) revert NameTooLong(); + ) external payable returns (bool status_) { - balances[senderOfTx] -= _amount; - balances[_recipient] += _amount; + if(bytes(_name).length > 8){ + revert SthWrong(); + } + + balances[msg.sender] -= _amount; + unchecked { + balances[_recipient] += _amount; + } emit Transfer(_recipient, _amount); - - return true; + return (true); } +/** + function updatePayment( + address _user, + uint256 _ID, + uint256 _amount, + PaymentType _type + ) external payable { - // 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 = _msgSender(); - - // 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 - // ); - // } - // } - // } + + onlyAdminOrOwner(msg.sender); + if (_ID < 0 || _amount < 0 || _user == address(0)){ + revert SthWrong(); + } + + unchecked { + + 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; + emit PaymentUpdated( + msg.sender, + _ID, + _amount, + payments[_user][ii].recipientName + ); + } + } + } + } +*/ function addToWhitelist(address _userAddrs, uint256 _tier) - public + external + payable + { - onlyAdminOrOwner(); - if(_tier >= type(uint8).max) revert InvalidTier(uint8(_tier)); - whitelist[_userAddrs] = _tier; - // if(_tier ) + onlyAdminOrOwner(msg.sender); + if (_tier > 255){ + revert SthWrong(); + } + 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 Anomally(); + whitelist[_userAddrs] = _tier; } emit AddedToWhitelist(_userAddrs, _tier); } @@ -203,35 +198,36 @@ contract GasContract is Ownable, Constants { function whiteTransfer( address _recipient, uint256 _amount - ) public checkIfWhiteListed(_msgSender()) { - address senderOfTx = _msgSender(); - whiteListStruct[senderOfTx] = ImportantStruct(_amount, 0, 0, 0, true, _msgSender()); - - if(balances[senderOfTx] < _amount) revert InsufficientBalance(); - if(_amount <= 3) revert AmountShouldExceed3(); + ) external payable { + + whiteListStruct[msg.sender] = ImportantStruct(_amount, true); + if(_amount < 3 ){ + revert SthWrong(); + } + if (_amount > balances[msg.sender]){ + revert SthWrong(); + } - balances[senderOfTx] -= _amount; - balances[_recipient] += _amount; - balances[senderOfTx] += whitelist[senderOfTx]; - balances[_recipient] -= whitelist[senderOfTx]; + balances[msg.sender] -= _amount; + unchecked { + balances[_recipient] += _amount; + balances[msg.sender] += whitelist[msg.sender]; + } + balances[_recipient] -= whitelist[msg.sender]; emit WhiteListTransfer(_recipient); } - function getPaymentStatus(address sender) public view returns (bool, uint256) { + function getPaymentStatus(address sender) external view returns (bool, uint256) { return (whiteListStruct[sender].paymentStatus, whiteListStruct[sender].amount); } - receive() external payable { - payable(_msgSender()).transfer(msg.value); - } - - fallback() external payable { - payable(_msgSender()).transfer(msg.value); + payable(msg.sender).transfer(msg.value); } -} - - + receive() external payable { + payable(msg.sender).transfer(msg.value); + } +} \ No newline at end of file diff --git a/src/IGasContract.sol b/src/IGasContract.sol deleted file mode 100644 index 5fdcdaf..0000000 --- a/src/IGasContract.sol +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED - -pragma solidity 0.8.18; - -interface IGasContract { - error InvalidAddress(); - error NotAnAdmin(address); - error LevelExceedBoundry(uint256); - error InsufficientBalance(uint256); - error TargetAlreadyAnAdmin(address); - error MaxNameLengthExceeded(uint256); - error AmountShouldBeAbove3(uint256); - error AmountShouldBeGreaterThanZero(); - error TargetAlreadyDeactivated(address); - - event AddedToWhitelist(address userAddress, uint256 tier); - 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); - - enum PaymentType { - Unknown, - BasicPayment, - Refund, - Dividend, - GroupPayment - } - - struct Payment { - PaymentType paymentType; - uint256 paymentID; - bool adminUpdated; - string recipientName; // max 8 characters - address recipient; - address admin; // administrators address - uint256 amount; - } - - struct History { - uint256 lastUpdate; - address updatedBy; - uint256 blockNumber; - } - - struct ImportantStruct { - uint256 amount; - uint256 valueA; // max 3 digits - uint256 bigValue; - uint256 valueB; // max 3 digits - bool paymentStatus; - address sender; - } - -} \ No newline at end of file