1.******* function getStakeTotal() private view returns (uint256 _stakes) {
- for (uint256 i = 0; i < holders.length; i++) {
- Position memory _position = positions[holders[i]];
_stakes += stake(_position);
}
}
function getStakeTotal() private view returns (uint256 _stakes) {
+ address[] storage Tempholders =holders;
+ mapping(address => Position) storage TempPositions =positions
+ uint256 Arraylength = Tempholders.length;
+ for (uint256 i ; i < Arraylength; ) {
+ Position memory _position = TempPositions[Tempholders[i]];
+ unchecked{
_stakes += stake(_position);
+ ++i; }
}
}
2.******* function getTstTotal() private view returns (uint256 _tst) {
- for (uint256 i = 0; i < holders.length; i++) {
- _tst += positions[holders[i]].TST;
}
- for (uint256 i = 0; i < pendingStakes.length; i++) {
_tst += pendingStakes[i].TST;
}
}
function getTstTotal() private view returns (uint256 _tst) {
+ address[] storage Tempholders =holders;
+ uint256 Arraylength = Tempholders.length;
+ mapping(address => Position) storage TempPositions =positions
+ for (uint256 i ; i < Arraylength; ) {
+ unchecked{
_tst += TempPositions[Tempholders[i]].TST;
+ ++i ;}
}
+ address[] storage TempPendingStakes =pendingStakes;
+ uint256 Arraylength2 = TempPendingStakes.length;
+ for (uint256 i ; i < Arraylength2; ) {
+ unchecked{
_tst += TempPendingStakes[i].TST;
+ ++i ;}
}
}
3.******** function holderPendingStakes(address _holder) private view returns (uint256 _pendingTST, uint256 _pendingEUROs) {
- for (uint256 i = 0; i < pendingStakes.length; i++) {
- PendingStake memory _pendingStake = pendingStakes[i];
if (_pendingStake.holder == _holder) {
_pendingTST += _pendingStake.TST;
_pendingEUROs += _pendingStake.EUROs;
}
}
}
function holderPendingStakes(address _holder) private view returns (uint256 _pendingTST, uint256 _pendingEUROs) {
+ address[] storage TempPendingStakes =pendingStakes;
+ uint256 Arraylength2 = TempPendingStakes.length;
+ for (uint256 i ; i < Arraylength; ) {
+ PendingStake memory _pendingStake = TempPendingStakes[i];
if (_pendingStake.holder == _holder) {
+ unchecked{
_pendingTST += _pendingStake.TST;
_pendingEUROs += _pendingStake.EUROs;
+ ++i; }
}
}
}
4******** function deleteHolder(address _holder) private {
- for (uint256 i = 0; i < holders.length; i++) {
- if (holders[i] == _holder) {
- holders[i] = holders[holders.length - 1];
holders.pop();
}
}
}
function deleteHolder(address _holder) private {
+ address[] storage Tempholders =holders;
+ uint256 Arraylength = Tempholders.length;
+ for (uint256 i ; i < Arraylength; ) {
+ if (Tempholders[i] == _holder) {
+ holders[i] = Tempholders[Arraylength - 1];
holders.pop();
+ return;
}
+ unchecked{ ++i; }
}
}
5.********* function addUniqueHolder(address _holder) private {
- for (uint256 i = 0; i < holders.length; i++) {
- if (holders[i] == _holder) return;
}
holders.push(_holder);
}
function addUniqueHolder(address _holder) private {
+ address[] storage Tempholders =holders;
+ uint256 Arraylength = Tempholders.length;
+ for (uint256 i ; i < Arraylength; ) {
+ if (Tempholders[i] == _holder) return;
+ unchecked{ ++i; }
}
holders.push(_holder);
}
5.******** function deletePendingStake(uint256 _i) private {
- for (uint256 i = _i; i < pendingStakes.length - 1; i++) {
- pendingStakes[i] = pendingStakes[i+1];
}
pendingStakes.pop();
}
function deletePendingStake(uint256 _i) private {
+ address[] storage TempPendingStakes =pendingStakes;
+ uint256 Arraylength = TempPendingStakes.length;
+ for (uint256 i=_i ; i < Arraylength-1; ) {
+ pendingStakes[i] = TempPendingStakes[i+1];
+ uncheked{ ++i; }
}
pendingStakes.pop();
}
6. ********** function consolidatePendingStakes() private {
uint256 deadline = block.timestamp - 1 days;
- for (int256 i = 0; uint256(i) < pendingStakes.length; i++) {
- PendingStake memory _stake = pendingStakes[uint256(i)];
if (_stake.createdAt < deadline) {
positions[_stake.holder].holder = _stake.holder;
positions[_stake.holder].TST += _stake.TST;
positions[_stake.holder].EUROs += _stake.EUROs;
deletePendingStake(uint256(i));
// pause iterating on loop because there has been a deletion. "next" item has same index
- i--;
}
}
}
function consolidatePendingStakes() private {
uint256 deadline = block.timestamp - 1 days;
+ address[] storage TempPendingStakes =pendingStakes;
+ uint256 Arraylength = TempPendingStakes.length;
+ for (uint256 i ; i < Arraylength; ) {
+ PendingStake memory _stake = TempPendingStakes[uint256(i)];
if (_stake.createdAt < deadline) {
positions[_stake.holder].holder = _stake.holder;
positions[_stake.holder].TST += _stake.TST;
positions[_stake.holder].EUROs += _stake.EUROs;
deletePendingStake(uint256(i));
// pause iterating on loop because there has been a deletion. "next" item has same index
+ unchecked{--i};
}
+ unchecked{++i};
}
}
7.********** function distributeFees(uint256 _amount) external onlyManager {
uint256 tstTotal = getTstTotal();
if (tstTotal > 0) {
IERC20(EUROs).safeTransferFrom(msg.sender, address(this), _amount);
- for (uint256 i = 0; i < holders.length; i++) {
- address _holder = holders[i];
- positions[_holder].EUROs += _amount * positions[_holder].TST / tstTotal;
}
- for (uint256 i = 0; i < pendingStakes.length; i++) {
- pendingStakes[i].EUROs += _amount * pendingStakes[i].TST / tstTotal;
}
}
}
function distributeFees(uint256 _amount) external onlyManager {
uint256 tstTotal = getTstTotal();
if (tstTotal > 0) {
IERC20(EUROs).safeTransferFrom(msg.sender, address(this), _amount);
+ address[] storage Tempholders =holders;
+ uint256 Arraylength = Tempholders.length;
+ for (uint256 i ; i < Arraylength; ) {
- address _holder = Tempholders[i];
+ unchecked {++i;}
- positions[_holder].EUROs += _amount * positions[_holder].TST / tstTotal;
}
- for (uint256 i = 0; i < pendingStakes.length; i++) {
- pendingStakes[i].EUROs += _amount * pendingStakes[i].TST / tstTotal;
}
}
}
8.***********
function distributeAssets(ILiquidationPoolManager.Asset[] memory _assets, uint256 _collateralRate, uint256 _hundredPC) external payable {
consolidatePendingStakes();
(,int256 priceEurUsd,,,) = Chainlink.AggregatorV3Interface(eurUsd).latestRoundData();
uint256 stakeTotal = getStakeTotal();
uint256 burnEuros;
uint256 nativePurchased;
- for (uint256 j = 0; j < holders.length; j++) {
- Position memory _position = positions[holders[j]];
uint256 _positionStake = stake(_position);
if (_positionStake > 0) {
for (uint256 i = 0; i < _assets.length; i++) {
ILiquidationPoolManager.Asset memory asset = _assets[i];
if (asset.amount > 0) {
(,int256 assetPriceUsd,,,) = Chainlink.AggregatorV3Interface(asset.token.clAddr).latestRoundData();
uint256 _portion = asset.amount * _positionStake / stakeTotal;
uint256 costInEuros = _portion * 10 ** (18 - asset.token.dec) * uint256(assetPriceUsd) / uint256(priceEurUsd)
* _hundredPC / _collateralRate;
if (costInEuros > _position.EUROs) {
_portion = _portion * _position.EUROs / costInEuros;
costInEuros = _position.EUROs;
}
_position.EUROs -= costInEuros;
rewards[abi.encodePacked(_position.holder, asset.token.symbol)] += _portion;
burnEuros += costInEuros;
if (asset.token.addr == address(0)) {
nativePurchased += _portion;
} else {
IERC20(asset.token.addr).safeTransferFrom(manager, address(this), _portion);
}
}
}
}
- positions[holders[j]] = _position;
}
if (burnEuros > 0) IEUROs(EUROs).burn(address(this), burnEuros);
returnUnpurchasedNative(_assets, nativePurchased);
}