I have an array of struct
, where I'm storing two uint
variables. The user can keep adding values to the array and I'm simply deleting the elements/deposits which are withdrawn completely.
The question is that this array (lockData[msg.sender]
) can potentially be huge, almost never ending if the user wants to keep adding funds. Hence, I want to know how good does the delete
keyword does to the time and gas cost preservation because I can't skip the number of iterations in any case.
Any suggestion for a new approach is welcome.
Here is the code for reference
function checkDepositData(address _user) public view returns(uint, uint, uint){
uint sum=0;
uint i;
uint start;
uint end;
// checking for first non zero index
for(i=0;i<lockData[_user].length; i++){
if(lockData[_user][i]._releaseTime < block.timestamp && lockData[_user][i]._amount>0) {
start=i;
break;
}
else{
i++;
if(lockData[_user][i]._releaseTime < block.timestamp && lockData[_user][i]._amount>0 && lockData[_user][i-1]._amount==0){
start=i;
break;
}
}
}
// start= the element where released deposition starts from
for(i=start;i<lockData[_user].length; i++){
if(lockData[_user][i]._releaseTime < block.timestamp){
sum+=lockData[_user][i]._amount;
end=i;
}
}
return (sum, start, end);
}
/*
_amount: Amount to lock
_releaseTime: Entered by the user
_start: The index in lockData[msg.sender] array till the point deposits are released
*/
function enterLOCK(uint256 _amount,uint _releaseTime, uint _start) public {
require((lockData[msg.sender].length - _start) <200, "Number of active depositions exceeded");
uint releaseTime = (_releaseTime * 1 days) + block.timestamp;
uint256 totalToken= token.balanceOf(address(this));
uint256 totalShares = totalSupply();
lockData[msg.sender].push(TimeLock(_amount, releaseTime));
if (totalShares == 0 || totalToken== 0) {
_mint(msg.sender, _amount);
} else {
uint256 what = _amount.mul(totalShares).div(totalToken);
_mint(msg.sender, what);
}
token.transferFrom(msg.sender, address(this), _amount);
}
function leavelock(uint256 _share) public {
uint256 totalShares = totalSupply();
uint256 what = _share.mul(token.balanceOf(address(this))).div(totalShares);
// temp vars
uint claimableAmt;
uint claimableIndexStart;
uint claimableIndexEnd;
(claimableAmt, claimableIndexStart, claimableIndexEnd)= checkDepositData(msg.sender);
require(claimableAmt< _share, "Cannot claim more than unlocked amount");
uint i;
uint withdrawalAmt= _share;
for(i=claimableIndexStart; i<= claimableIndexEnd;i++){
/*
E.g. [200, 400, 200, 500, 300], _share=700
i) _share= _share-deposit[0]= 700-200= 500
ii) _share= _share (500) - deposit[1]= 500-400= 100
iii) (first if condn.) deposit[2]= deposit[2] - _share= 200-100= 100
END
*/
if(lockData[msg.sender][i]._amount > withdrawalAmt){
lockData[msg.sender][i]._amount-= withdrawalAmt;
break;
}else{
withdrawalAmt-= lockData[msg.sender][i]._amount;
delete lockData[msg.sender][i]; // sets the values to 0, null, false etc.
}
}
// Actual transfer
_burn(msg.sender, _share);
token.transfer(msg.sender, what);
}