-
Notifications
You must be signed in to change notification settings - Fork 266
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
Unexpected Balances #63
Closed
Closed
Changes from 8 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
02ee29a
Add force-feeding.md
795eb3a
Update force-feeding.md
indeqs bbc5bbf
Update README.md
indeqs 3d6a14a
Merge branch 'master' into force-feeding
indeqs d6e9855
Update force-feeding.md
indeqs 3ff0543
Update force-feeding.md
indeqs aa478ed
Update force-feeding.md
indeqs a7eae8d
Update README.md
indeqs 4cf5b5a
Update README.md
indeqs 0198f30
Update branch force-feeding
0268afe
Add unexpected-balances.md
0f89366
Update unexpected-balances.md
indeqs 642aa1d
Update unexpected-balances.md
indeqs File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
# Unexpected Ether Transfer | ||
|
||
Force-feeding is a technique where an attacker sends Ether directly to a smart contract address without invoking any of its functions. This can disrupt the contract's internal accounting mechanisms, particularly if the contract relies on balance checks for its logic. | ||
|
||
In typical smart contract operation, Ether is sent to a contract via a transaction that calls a payable function or invokes the `receive()` or `fallback()` functions. If a contract lacks these functions, transactions sending Ether to it will normally be reverted, ensuring the contract does not inadvertently receive funds. | ||
|
||
Force-feeding bypasses this by sending Ether in a manner that doesn't require calling the contract's functions, thereby avoiding the checks and logic coded in Solidity. | ||
|
||
## Force Feeding Methods | ||
|
||
### Block Rewards and Coinbase | ||
|
||
In Proof of Stake systems like Ethereum, validators earn block rewards for successfully adding blocks to the blockchain. These rewards are sent to an address known as the **coinbase address**. Validators typically set this address to their own wallets, but an attacker-validator can set it to a target smart contract’s address. | ||
|
||
Since block reward transfers are handled at the protocol level, they bypass Solidity-level checks. As a result, the target contract receives Ether directly as part of the block reward, regardless of any Solidity-coded restrictions. | ||
|
||
## Preventing Force Feeding | ||
|
||
To safeguard against force-feeding, consider the following strategies: | ||
Comment on lines
+17
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note to self to come back to reconsider these prevention methods further |
||
|
||
### 1. Avoid Using the Contract’s Balance Directly | ||
|
||
Instead of relying on `address(this).balance` for critical logic, maintain an internal accounting system. For example: | ||
|
||
```solidity | ||
/// DO NOT USE IN PRODUCTION | ||
/// ONLY MEANT TO SERVE AS AN EXAMPLE | ||
|
||
mapping(address => uint256) internalBalances; | ||
|
||
function deposit() external payable { | ||
internalBalances[msg.sender] += msg.value; | ||
} | ||
|
||
function withdraw(uint256 amount) external { | ||
require(internalBalances[msg.sender] >= amount, "Insufficient balance"); | ||
internalBalances[msg.sender] -= amount; | ||
payable(msg.sender).transfer(amount); | ||
} | ||
|
||
function getBalance(address user) external view returns (uint256) { | ||
return internalBalances[user]; | ||
} | ||
``` | ||
|
||
### 2. Immediate Funds Transfer | ||
|
||
Instead of holding funds within the contract, immediately transfer received Ether to a secure, off-contract storage or another smart contract that handles funds securely: | ||
|
||
```solidity | ||
address payable public safeAddress = payable(0xSafeAddress); | ||
|
||
receive() external payable { | ||
safeAddress.transfer(msg.value); | ||
} | ||
``` | ||
|
||
### 3. Event-Based Balance Tracking | ||
|
||
Use events for deposit and withdrawal tracking, enabling off-chain monitoring and cross-verification of the contract’s balance: | ||
|
||
```solidity | ||
event Deposit(address indexed from, uint256 amount); | ||
event Withdrawal(address indexed to, uint256 amount); | ||
|
||
function deposit() external payable { | ||
internalBalances[msg.sender] += msg.value; | ||
emit Deposit(msg.sender, msg.value); | ||
} | ||
|
||
function withdraw(uint256 amount) external { | ||
require(internalBalances[msg.sender] >= amount, "Insufficient balance"); | ||
internalBalances[msg.sender] -= amount; | ||
payable(msg.sender).transfer(amount); | ||
emit Withdrawal(msg.sender, amount); | ||
} | ||
``` | ||
|
||
Off-chain systems can then monitor these events and compare them with the on-chain state to ensure integrity. | ||
|
||
## Sources | ||
- [Solidity coinbase address](https://docs.soliditylang.org/en/latest/units-and-global-variables.html#block-and-transaction-properties) | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should update the name here, also would be good to change the filename as well