EthSecurity
5.22K subscribers
112 photos
20 files
762 links
Download Telegram
Fully repaying a loan will result in debt payment being lost.When a loan is fully repaid the loan storage is deleted. Since loan is a storage reference to the loan, loan.lender will return address(0) after the loan has been deleted. This will result in the debt being transferred to address(0) instead of the lender. Some ERC20 tokens will revert when being sent to address(0) but a large number will simply be sent there and lost forever.In Cooler#repay the loan storage associated with the loanID being repaid is deleted. loan is a storage reference so when loans[loanID] is deleted so is loan. The result is that loan.lender is now address(0) and the loan payment will be sent there instead.

Recommendation:
Send collateral/debt then delete:

- if (repaid == loan.amount) delete loans[loanID];
+ if (repaid == loan.amount) {
+ debt.transferFrom(msg.sender, loan.lender, loan.amount);
+ collateral.transfer(owner, loan.collateral);
+ delete loans[loanID];
+ return;
+ }
@EthSecurity1
Some pitfalls of handling signatures in smart contracts:

1. Using ecrecover and not checking if it returned address(0) (invalid signature)
2. Signature malleability
a) by using EIP2098 (compact signature)
b) by flipping s & v (documented in EIP2, but ecrecover won't revert) @EthSecurity1
21
1-Pick the right audit
2-Get a intuitive feel of protocol
3-Whiteboard key workflow
4-Identify focus areas
5-Line-by-Line code review
6-Review current test cases
7-Write POCs
8-Riview finding
@EthSecurity1
🔥4👍21
Gas Griefing Attack
Imagine you have a smart contract that uses the require statement to perform a call to another contract using the to.call function. You want to make sure that the callee contract receives a specific amount of gas that you specify.
However, there are two reasons why the require call alone cannot guarantee this:
-Gas required for the call itself: When you make the call, the gas required for the call's operations and memory usage will further reduce the available gas. This means that the actual gas available at the moment of the call will be lower than what you initially expected.
-The 63/64 rule: Even if the gas available at the point of the call seems sufficient, the Ethereum protocol applies the 63/64 rule. This rule reduces the available gas even more, potentially affecting the amount of gas the callee contract receives. The remaining gas (1/64 of the gas required) can still be enough for the rest of the transaction to succeed, allowing the call to continue. @EthSecurity1
2👍2
Liquidations are enabled when repayments are disabled, causing borrowers to lose funds without a chance to repay

Summary:

Debt repaying can be temporary disabled by the admin of BlueBerryBank, however liquidations are not disabled during this period. As a result, users' positions can accumulate more borrow interest, go above the liquidation threshold, and be liquidated, while users aren't able to repay the debts.
Vulnerability Detail:

The owner of BlueBerryBank can disable different functions of the contract, including repayments. However, while repayments are disabled liquidations are still allowed. As a result, when repayments are disabled, liquidator can liquidate any position, and borrowers won't be able to protect against that by repaying their debts. Thus, borrowers will be forced to lose their collateral.

Impact:

Positions will be forced to liquidations while their owners won't be able to repay debts to avoid liquidations @EthSecurity1
👍51
I created web3 privacy channel
@web3privacy1
4👍1🤔1
whitepaper-v4-draft.pdf
383.1 KB
Uniswap v4 enables powerful new ways to customize liquidity pools by introducing “hooks”.

Hooks add entirely new functionality to pools, such as dynamically adjusting fees or creating new order types

@EthSecurity1
🦄6
Here are top 3 takeaways from uniswap v4 🧵
1. Gas is king. ⛽️

One clever trick v4 uses is storing flag data in the address. Note that it's much cheaper to load the address (constant per call frame) compared to memory accesses. @EthSecurity1
2. Everything's a flash loan! ⚡️

Callers need to first "lock", which sets up a flashloan-like accounting structure. This also helps with gas by delaying token transfers to the end. Note that this is _not_ a reentrancy guard as some people have been claiming.@EthSecurity1
🔥1
3. Hook management is complex. 🎣

The whitepaper talks about 8 separate hook locations. Proper state management across each will be interesting.

Some ideas off the top of my head:
1. Multiple locks in the same tx
2. Directly calling hooks
3. Re-entrant behavior
@EthSecurity1
🔥5
Losing fund during force deployment #zksync

If anon of this call is unsuccessful, the whole transaction will not revert, and the loop continues to deploy all the contract on the provided newAddress.
If anon reason, the deployment was not successful, the transferred ETH will remain in ContractDeployer, and can not be used for the next deployments (because the aggregated amount is compared with msg.value not the ETH balance of the contract).FORCE_DEPLOYER fund will be in ContractDeployer, and it can not be easily recoverred.
mitigation:
for (uint256 i = 0; i < deploymentsLength; ++i) {
try
this.forceDeployOnAddress{value: _deployments[i].value}(
_deployments[i],
msg.sender
)
{} catch {
ETH_TOKEN_SYSTEM_CONTRACT.transferFromTo(
address(this),
SomeAddress,
_deployments[i].value
);
}
}
}
@EthSecurity1
3
Lender and liquidator can collude to block auction and seize collateral


If a lender offers a loan denominated in an ERC20 token that blocks transfers to certain addresses (for example, the USDT and USDC blocklist), they may collude with a liquidator (or act as the liquidator themselves) to prevent loan payments, block all bids in the liquidation auction, and seize the borrower's collateral by transferring a LienToken to a blocked address.

This may be difficult to mitigate. Transferring a lien to a blocklisted address is one mechanism for this attack using USDT and USDC, but there are other ways arbitrary ERC20s might revert. Two potential options:

Mitigation:
Maintain an allowlist of supported ERC20s and limit it to well behaved tokens—WETH, DAI,...
Do not "push" payments to payees on loan payment or auction settlement, but handle this in two steps—first receiving payment from the borrower or Seaport auction and storing it in escrow then allowing lien owners to "pull" the escrowed payment.
@EthSecurity1
3
Hundred Finance attack vector ( that caused ~7m$ loss) explanation in step-wise diagram style.



Excalidraw Link : https://t.co/wTUC8W3kjf @EthSecurity1
🤔3👍2🔥1
In this example, the _asset can be an ERC20 (!= address(0)) or ETH (== address(0)).
When transferring ERC20 tokens, it's crucial to ensure that the user doesn't send msg.value during that transaction. Otherwise, the value they send will be lost.
t's also important to check if the msg.value is equal to the amount when the asset is actually ETH (== address(0)). @EthSecurity1
One of my favourite Foundry features is running tests in watch mode.
It allows me to iterate really fast by changing the solidity files while my tests are being re-run.
e.g. $ forge test --match-test test_NameOfYourTest --watch
More on the command: https://book.getfoundry.sh/forge/tests?highlight=watch#watch-mode @EthSecurity1
👍42🔥2