The BalancerLiquidity smart contract provides a lightweight interface to interact with the Balancer RETH/WETH liquidity pool. It allows users to:
- Join the pool by depositing
RETH,WETH, or both. - Exit the pool by redeeming Balancer Pool Tokens (BPT) for
RETH.
The contract is designed for composability, simplicity, and trustless use with no admin roles or upgrade mechanisms.
import { IERC20 } from "../interface/IERC20.sol";
import { IRETH } from "../interface/rocket-pool/IRETH.sol";
import { IVault } from "../interface/IVault.sol";
import {
WETH, RETH, BALANCER_VAULT,
BALANCER_POOL_RETH_WETH, BALANCER_POOL_ID_RETH_WETH
} from "./Constants.sol";- User calls
join()with RETH and/or WETH. - Contract transfers and approves tokens to the Vault.
- Liquidity is added and BPT is minted.
- Any unused tokens are refunded.
- User calls
exit()with the amount of BPT to redeem. - Contract transfers BPT to the Vault.
- RETH is redeemed and sent to the user.
Key Imports:
IERC20: Standard ERC-20 interfaceIRETH: Rocket Pool's RETH token interfaceIVault: Balancer Vault interfaceConstants: Immutable addresses used for tokens and pools
- Minimal token approvals (per call)
- Token refund for unused balances
- Slippage protection using
minAmountsOut - Token ordering enforced (RETH before WETH)
The current implementation is minimal by design. However, the following enhancements are recommended to improve safety, flexibility, and interoperability.
Purpose:
Protect against potential reentrancy via token callbacks or future changes.
Suggestion:
Use OpenZeppelin’s ReentrancyGuard on join() and exit().
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
contract BalancerLiquidity is ReentrancyGuard {
function join(...) external nonReentrant { ... }
function exit(...) external nonReentrant { ... }
}Current:
Only RETH is returned on exit().
Improvement:
Allow users to specify:
- Desired token index (0 for RETH, 1 for WETH), or
- Use
EXACT_BPT_IN_FOR_TOKENS_OUTto receive both tokens proportionally.
Current:
Hardcoded join/exit strategies.
Improvement:
Expose JoinKind, ExitKind, and userData to enable:
- Proportional joins
- More efficient exits
- DEX aggregator integrations
Current:
No on-chain events for off-chain tracking.
Improvement:
Emit Joined and Exited events for better UX and indexing.
event Joined(address indexed user, uint256 rethIn, uint256 wethIn, uint256 bptOut);
event Exited(address indexed user, uint256 bptIn, uint256 rethOut, uint256 wethOut);Problem:
No way to recover mistakenly sent tokens.
Improvement:
Implement a sweep() function restricted to a trusted role or DAO.
Only allow non-core tokens (not RETH/WETH/BPT) to be swept.