-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
escrow contract #894
base: main
Are you sure you want to change the base?
escrow contract #894
Conversation
contracts/escrow/Escrow.sol
Outdated
function cancelExpiredLocks(uint256 jobId,address token,address payer,address payee) public{ | ||
uint256 index; | ||
//since solidy does not supports dynamic arrays, we need to count first | ||
uint256 found=0; | ||
for(index=0;index<locks.length;index++){ | ||
if(locks[index].expiry<block.timestamp && | ||
( | ||
(jobId==0 || jobId==locks[index].jobId) && | ||
(token==address(0) || token==locks[index].token) && | ||
(payer==address(0) || payer==locks[index].payer) && | ||
(payee==address(0) || payee==locks[index].payee) | ||
) | ||
){ | ||
found++; | ||
} | ||
} | ||
// bail out if we don't have any expired matching locks | ||
if(found==0) return; | ||
uint256[] memory indexToDelete=new uint256[](found); | ||
uint256 currentIndex=0; | ||
// now actually do the work | ||
for(index=0;index<locks.length;index++){ | ||
if(locks[index].expiry<block.timestamp && | ||
( | ||
(jobId==0 || jobId==locks[index].jobId) && | ||
(token==address(0) || token==locks[index].token) && | ||
(payer==address(0) || payer==locks[index].payer) && | ||
(payee==address(0) || payee==locks[index].payee) | ||
) | ||
){ | ||
//cancel each lock, one by one | ||
//update auths | ||
for(uint256 i=0;i<userAuths[locks[index].payer][locks[index].token].length;i++){ | ||
if(userAuths[payer][token][i].payee==locks[index].payee){ | ||
userAuths[payer][token][i].currentLockedAmount-=locks[index].amount; | ||
userAuths[payer][token][i].currentLocks-=1; | ||
} | ||
} | ||
//update user funds | ||
funds[locks[index].payer][locks[index].token].available+=locks[index].amount; | ||
funds[locks[index].payer][locks[index].token].locked-=locks[index].amount; | ||
emit Canceled(locks[index].payee,locks[index].jobId,locks[index].token, | ||
locks[index].payer,locks[index].amount); | ||
indexToDelete[currentIndex]=index; | ||
currentIndex++; | ||
} | ||
} | ||
//delete the locks | ||
for(index=0;index<indexToDelete.length;index++){ | ||
locks[indexToDelete[index]]=locks[locks.length-1]; | ||
locks.pop(); | ||
} | ||
} |
Check notice
Code scanning / Slither
Block timestamp Low
Dangerous comparisons:
- index < length
- locks[index].expiry < block.timestamp && ((jobId == 0 || jobId == locks[index].jobId) && (token == address(0) || token == locks[index].token) && (payer == address(0) || payer == locks[index].payer) && (payee == address(0) || payee == locks[index].payee))
- index < length
- locks[index].expiry < block.timestamp && ((jobId == 0 || jobId == locks[index].jobId) && (token == address(0) || token == locks[index].token) && (payer == address(0) || payer == locks[index].payer) && (payee == address(0) || payee == locks[index].payee))
- userAuths[payer][token][i].payee == locks[index].payee
contracts/escrow/Escrow.sol
Outdated
function cancelExpiredLocks(uint256 jobId,address token,address payer,address payee) public{ | ||
uint256 index; | ||
//since solidy does not supports dynamic arrays, we need to count first | ||
uint256 found=0; | ||
for(index=0;index<locks.length;index++){ | ||
if(locks[index].expiry<block.timestamp && | ||
( | ||
(jobId==0 || jobId==locks[index].jobId) && | ||
(token==address(0) || token==locks[index].token) && | ||
(payer==address(0) || payer==locks[index].payer) && | ||
(payee==address(0) || payee==locks[index].payee) | ||
) | ||
){ | ||
found++; | ||
} | ||
} | ||
// bail out if we don't have any expired matching locks | ||
if(found==0) return; | ||
uint256[] memory indexToDelete=new uint256[](found); | ||
uint256 currentIndex=0; | ||
// now actually do the work | ||
for(index=0;index<locks.length;index++){ | ||
if(locks[index].expiry<block.timestamp && | ||
( | ||
(jobId==0 || jobId==locks[index].jobId) && | ||
(token==address(0) || token==locks[index].token) && | ||
(payer==address(0) || payer==locks[index].payer) && | ||
(payee==address(0) || payee==locks[index].payee) | ||
) | ||
){ | ||
//cancel each lock, one by one | ||
//update auths | ||
for(uint256 i=0;i<userAuths[locks[index].payer][locks[index].token].length;i++){ | ||
if(userAuths[payer][token][i].payee==locks[index].payee){ | ||
userAuths[payer][token][i].currentLockedAmount-=locks[index].amount; | ||
userAuths[payer][token][i].currentLocks-=1; | ||
} | ||
} | ||
//update user funds | ||
funds[locks[index].payer][locks[index].token].available+=locks[index].amount; | ||
funds[locks[index].payer][locks[index].token].locked-=locks[index].amount; | ||
emit Canceled(locks[index].payee,locks[index].jobId,locks[index].token, | ||
locks[index].payer,locks[index].amount); | ||
indexToDelete[currentIndex]=index; | ||
currentIndex++; | ||
} | ||
} | ||
//delete the locks | ||
for(index=0;index<indexToDelete.length;index++){ | ||
locks[indexToDelete[index]]=locks[locks.length-1]; | ||
locks.pop(); | ||
} | ||
} |
Check warning
Code scanning / Slither
Costly operations inside a loop Warning
- locks.pop()
escrow contract
🚨 Report Summary
For more details view the full report in OpenZeppelin Code Inspector |
function getLocks(address token,address payer,address payee) public view returns (lock[] memory){ | ||
// since solidty does not supports dynamic memory arrays, we need to calculate the return size first | ||
uint256 size=0; | ||
uint256 length=locks.length; | ||
for(uint256 i=0;i<length;i++){ | ||
if( | ||
(address(token)==address(0) || address(token)==locks[i].token) || | ||
(address(payee)==address(0) || address(payee)==locks[i].payee) || | ||
(address(payer)==address(0) || address(payer)==locks[i].payer) | ||
){ | ||
size++; | ||
} | ||
} | ||
|
||
lock[] memory tempPendings=new lock[](size); | ||
size=0; | ||
for(uint256 i=0;i<length;i++){ | ||
if( | ||
(address(token)==address(0) || address(token)==locks[i].token) || | ||
(address(payee)==address(0) || address(payee)==locks[i].payee) || | ||
(address(payer)==address(0) || address(payer)==locks[i].payer) | ||
){ | ||
tempPendings[size]=locks[i]; | ||
size++; | ||
} | ||
} | ||
return(tempPendings); | ||
} |
Check notice
Code scanning / Slither
Block timestamp Low
Dangerous comparisons:
- i < length
- (address(token) == address(0) || address(token) == locks[i].token) || (address(payee) == address(0) || address(payee) == locks[i].payee) || (address(payer) == address(0) || address(payer) == locks[i].payer)
- i_scope_0 < length
- (address(token) == address(0) || address(token) == locks[i_scope_0].token) || (address(payee) == address(0) || address(payee) == locks[i_scope_0].payee) || (address(payer) == address(0) || address(payer) == locks[i_scope_0].payer)
function createLock(uint256 jobId,address token,address payer,uint256 amount,uint256 expiry) external{ | ||
require(payer!=address(0),'Invalid payer'); | ||
require(token!=address(0),'Invalid token'); | ||
require(amount>0,"Invalid amount"); | ||
require(jobId>0,"Invalid jobId"); | ||
auth memory tempAuth=auth(address(0),0,0,0,0,0); | ||
uint256 index; | ||
require(funds[payer][token].available>=amount,"Payer does not have enough funds"); | ||
uint256 length=userAuths[payer][token].length; | ||
for(index=0;index<length;index++){ | ||
if(msg.sender==userAuths[payer][token][index].payee) { | ||
tempAuth=userAuths[payer][token][index]; | ||
break; | ||
} | ||
} | ||
require(tempAuth.payee==msg.sender,"No auth found"); | ||
require(expiry<=tempAuth.maxLockSeconds,"Expiry too high"); | ||
require(amount<= tempAuth.maxLockedAmount,"Amount too high"); | ||
require(tempAuth.currentLockedAmount+amount<=tempAuth.maxLockedAmount,"Exceeds maxLockedAmount"); | ||
require(tempAuth.currentLocks<tempAuth.maxLockCounts,"Exceeds maxLockCounts"); | ||
// check jobId | ||
length=locks.length; | ||
for(uint256 i=0;i<length;i++){ | ||
if(locks[i].payer==payer && locks[i].payee==msg.sender && locks[i].jobId==jobId){ | ||
revert("JobId already exists"); | ||
} | ||
} | ||
// update auths | ||
userAuths[payer][token][index].currentLockedAmount+=amount; | ||
userAuths[payer][token][index].currentLocks+=1; | ||
// update user funds | ||
funds[payer][token].available-=amount; | ||
funds[payer][token].locked+=amount; | ||
// create the lock | ||
locks.push(lock(jobId,payer,msg.sender,amount,block.timestamp+expiry,token)); | ||
emit Lock(payer,msg.sender,jobId,amount,expiry,token); | ||
} |
Check warning
Code scanning / Slither
Dangerous strict equalities Medium
- locks[i].payer == payer && locks[i].payee == msg.sender && locks[i].jobId == jobId
function cancelExpiredLocks(uint256 jobId,address token,address payer,address payee) public{ | ||
uint256 index; | ||
//since solidy does not supports dynamic arrays, we need to count first | ||
uint256 found=0; | ||
uint256 length=locks.length; | ||
for(index=0;index<length;index++){ | ||
if(locks[index].expiry<block.timestamp && | ||
( | ||
(jobId==0 || jobId==locks[index].jobId) && | ||
(token==address(0) || token==locks[index].token) && | ||
(payer==address(0) || payer==locks[index].payer) && | ||
(payee==address(0) || payee==locks[index].payee) | ||
) | ||
){ | ||
found++; | ||
} | ||
} | ||
// bail out if we don't have any expired matching locks | ||
if(found==0) return; | ||
uint256[] memory indexToDelete=new uint256[](found); | ||
uint256 currentIndex=0; | ||
// now actually do the work | ||
for(index=0;index<length;index++){ | ||
if(locks[index].expiry<block.timestamp && | ||
( | ||
(jobId==0 || jobId==locks[index].jobId) && | ||
(token==address(0) || token==locks[index].token) && | ||
(payer==address(0) || payer==locks[index].payer) && | ||
(payee==address(0) || payee==locks[index].payee) | ||
) | ||
){ | ||
//cancel each lock, one by one | ||
//update auths | ||
uint256 authsLength=userAuths[locks[index].payer][locks[index].token].length; | ||
for(uint256 i=0;i<authsLength;i++){ | ||
if(userAuths[payer][token][i].payee==locks[index].payee){ | ||
userAuths[payer][token][i].currentLockedAmount-=locks[index].amount; | ||
userAuths[payer][token][i].currentLocks-=1; | ||
} | ||
} | ||
//update user funds | ||
funds[locks[index].payer][locks[index].token].available+=locks[index].amount; | ||
funds[locks[index].payer][locks[index].token].locked-=locks[index].amount; | ||
emit Canceled(locks[index].payee,locks[index].jobId,locks[index].token, | ||
locks[index].payer,locks[index].amount); | ||
indexToDelete[currentIndex]=index; | ||
currentIndex++; | ||
} | ||
} | ||
//delete the locks | ||
uint256 delLength=indexToDelete.length; | ||
for(index=0;index<delLength;index++){ | ||
locks[indexToDelete[index]]=locks[locks.length-1]; | ||
locks.pop(); | ||
} | ||
} |
Check warning
Code scanning / Slither
Dangerous strict equalities Medium
- locks[index].expiry < block.timestamp && ((jobId == 0 || jobId == locks[index].jobId) && (token == address(0) || token == locks[index].token) && (payer == address(0) || payer == locks[index].payer) && (payee == address(0) || payee == locks[index].payee))
function cancelExpiredLocks(uint256 jobId,address token,address payer,address payee) public{ | ||
uint256 index; | ||
//since solidy does not supports dynamic arrays, we need to count first | ||
uint256 found=0; | ||
uint256 length=locks.length; | ||
for(index=0;index<length;index++){ | ||
if(locks[index].expiry<block.timestamp && | ||
( | ||
(jobId==0 || jobId==locks[index].jobId) && | ||
(token==address(0) || token==locks[index].token) && | ||
(payer==address(0) || payer==locks[index].payer) && | ||
(payee==address(0) || payee==locks[index].payee) | ||
) | ||
){ | ||
found++; | ||
} | ||
} | ||
// bail out if we don't have any expired matching locks | ||
if(found==0) return; | ||
uint256[] memory indexToDelete=new uint256[](found); | ||
uint256 currentIndex=0; | ||
// now actually do the work | ||
for(index=0;index<length;index++){ | ||
if(locks[index].expiry<block.timestamp && | ||
( | ||
(jobId==0 || jobId==locks[index].jobId) && | ||
(token==address(0) || token==locks[index].token) && | ||
(payer==address(0) || payer==locks[index].payer) && | ||
(payee==address(0) || payee==locks[index].payee) | ||
) | ||
){ | ||
//cancel each lock, one by one | ||
//update auths | ||
uint256 authsLength=userAuths[locks[index].payer][locks[index].token].length; | ||
for(uint256 i=0;i<authsLength;i++){ | ||
if(userAuths[payer][token][i].payee==locks[index].payee){ | ||
userAuths[payer][token][i].currentLockedAmount-=locks[index].amount; | ||
userAuths[payer][token][i].currentLocks-=1; | ||
} | ||
} | ||
//update user funds | ||
funds[locks[index].payer][locks[index].token].available+=locks[index].amount; | ||
funds[locks[index].payer][locks[index].token].locked-=locks[index].amount; | ||
emit Canceled(locks[index].payee,locks[index].jobId,locks[index].token, | ||
locks[index].payer,locks[index].amount); | ||
indexToDelete[currentIndex]=index; | ||
currentIndex++; | ||
} | ||
} | ||
//delete the locks | ||
uint256 delLength=indexToDelete.length; | ||
for(index=0;index<delLength;index++){ | ||
locks[indexToDelete[index]]=locks[locks.length-1]; | ||
locks.pop(); | ||
} | ||
} |
Check warning
Code scanning / Slither
Dangerous strict equalities Medium
- locks[index].expiry < block.timestamp && ((jobId == 0 || jobId == locks[index].jobId) && (token == address(0) || token == locks[index].token) && (payer == address(0) || payer == locks[index].payer) && (payee == address(0) || payee == locks[index].payee))
Fixes #893