Treasury
Last updated
Treasury is a minimal yet crucial smart contract that securely stores and allows controlled withdrawals of both native ETH and ERC20 tokens. Owned by a single address, it enforces strict access control on asset movements via onlyOwner
and mitigates re-entrant calls through nonReentrant
. This design ensures that only the contract owner can authorize withdrawals and that no re-entrancy exploits can siphon funds.
Key Attributes:
Custody of Funds: Holds ERC20 tokens and ETH in a secure manner.
Restricted Withdrawals: Only the contract’s owner can withdraw funds, specifying the token address, amount, and recipient.
Non-Reentrant Calls: Uses ReentrancyGuard
to prevent complex re-entrancy exploits during withdrawals.
By implementing the ITreasury
interface, Treasury provides a standardized API (the withdraw
function) and emits an event (TokenWithdrawn
) whenever funds are moved out.
Ownable (OpenZeppelin)
Allows the contract to have an owner who can perform restricted operations. In this case, only the owner can call withdraw
.
ReentrancyGuard (OpenZeppelin)
Protects critical functions from re-entrancy attacks. The withdraw
function uses the nonReentrant
modifier.
ITreasury (Custom Interface)
Declares the withdraw
function signature and TokenWithdrawn
event. The contract implements these specifications.
Additional External References:
SafeERC20, IERC20 (OpenZeppelin): Used to safely transfer ERC20 tokens in the withdraw
function.
Address (OpenZeppelin): Provides the sendValue
method for securely transferring ETH.
The Treasury contract does not introduce mutable storage variables beyond those inherited from its parent classes. However, it defines:
owner (Ownable.sol)
A variable inherited from Ownable indicating the contract owner. Managed internally by the Ownable library’s _owner
storage variable.
No other custom state variables are defined. The contract relies on the OpenZeppelin libraries for ownership tracking and reentrancy control.
constructor(address owner_) Ownable(owner_) {}
Description:
The constructor takes a single parameter, owner_
, which designates the address to be assigned as the contract owner via Ownable. This ownership implies exclusive access to withdraw
.
Parameters:
owner_
: The address that will be granted ownership of the contract upon deployment.
Effects:
Calls Ownable(owner_)
constructor to set the provided owner_
as the owner.
No additional logic is performed here.
receive() external payable {}
Description:
A receive fallback function that allows the contract to accept native ETH transfers (e.g., via send
or transfer
with no calldata). This function does not store or otherwise process the ETH, aside from receiving it into the contract’s balance.
withdraw(address token_, uint256 amount_, address recipient_)
function withdraw(
address token_,
uint256 amount_,
address recipient_
)
external
onlyOwner
nonReentrant
Description:
Allows the contract owner to withdraw either an ERC20 token or native ETH from the treasury to a specified recipient_
. If token_
is the zero address (address(0)
), it indicates a withdrawal of ETH. Otherwise, it withdraws the specified ERC20 token using a safe transfer.
Parameters:
token_
: The address of the ERC20 token to withdraw. If address(0)
, the function sends ETH instead of tokens.
amount_
: The amount of tokens (or ETH) to withdraw.
recipient_
: The address that will receive the withdrawn tokens or ETH.
Checks & Effects:
The function uses onlyOwner
to ensure only the contract’s owner can invoke it.
Uses nonReentrant
from ReentrancyGuard to prevent nested re-entrant calls.
If token_ == address(0)
, uses Address.sendValue
to send amount_
of ETH to recipient_
.
Otherwise, calls safeTransfer
on IERC20(token_)
to transfer amount_
tokens to recipient_
.
Events:
Emits TokenWithdrawn(token_, amount_, recipient_)
upon a successful withdrawal, logging details for transparency.
TokenWithdrawn(address indexed token, uint256 indexed amount, address indexed recipient)
Emitted When:
The withdraw
function completes successfully, whether removing ETH or ERC20 tokens.
Parameters:
token
: The address of the token being withdrawn. Zero address if ETH.
amount
: The quantity of tokens or ETH withdrawn.
recipient
: The address that received the withdrawn funds.
Treasury acts as a straightforward contract for securely holding and releasing ETH or ERC20 tokens under the CrossCurve ecosystem. With Ownable restricting withdraw
calls to the contract owner and ReentrancyGuard ensuring robust security, the Treasury provides a trustworthy store for tokens:
Secure Custody: Only an authorized owner can move assets out.
Versatile Withdrawals: Supports both ETH and arbitrary ERC20 tokens using standardized SafeERC20 operations.
Transparent Logging: The TokenWithdrawn
event ensures on-chain traceability of funds outflow.
This minimal approach ensures clarity, security, and traceable control over treasury assets within the CrossCurve framework.