Deposit address that forwards its ether and any ERC-20 balance to one fixed wallet, driven entirely by a controller account.
Historical Significance
The failure events are the interesting half. A sweeper that reverts on a bad token strands the whole batch; this one records the outcome and moves on, which is what an operator running thousands of deposit addresses actually needs. Fixing the destination wallet in the constructor and leaving out a setter means a compromised controller can redirect who signs the sweeps but never where the money lands.
Key Facts
Description
Storage holds two addresses: a controller, and the wallet everything drains into. The wallet is fixed at construction and has no setter, so a deployed vault can only ever pay one destination.
The fallback is payable and empty, which is the whole point of the contract: it is an address a customer can be given to send ether to. collect takes an amount and sends that much ether to the wallet. doTransfer takes a token address and an amount and calls transfer on it with the wallet as the recipient, which sweeps ERC-20 deposits the same way. Both are restricted to the controller, and changeController lets the controller hand over to a successor.
Neither sweep reverts on failure. Each one checks the boolean result and emits either a success event or a matching failure event, so a token that returns false instead of throwing still leaves a record on chain.
Source Verified
Byzantium Era
First Metropolis hard fork. Added zk-SNARK precompiles, REVERT opcode, and staticcall.
Bytecode Overview
Verified Source Available
This contract has verified source code.
View Verification ProofShow source code (Solidity)
// Submitted by EthereumHistory (ethereumhistory.com)
pragma solidity ^0.4.13;
contract Token {
function transfer(address _to, uint256 _amount) returns (bool success);
}
contract Controlled {
address public controller;
function Controlled() { controller = msg.sender; }
modifier onlyController { require(msg.sender == controller); _; }
function changeController(address _newController) onlyController {
controller = _newController;
}
}
contract Vault is Controlled {
address wallet;
event LogTransfer(address _to, uint256 _amount, address _token);
event LogTransferFailure(address _to, uint256 _amount, address _token);
event LogCollection(address _to, uint256 _amount);
event LogCollectionFailure(address _to, uint256 _amount);
function Vault(address _wallet) { wallet = _wallet; }
function () payable { }
function doTransfer(address _token, uint256 _amount) onlyController {
if (Token(_token).transfer(wallet, _amount)) {
LogTransfer(wallet, _amount, _token);
} else {
LogTransferFailure(wallet, _amount, _token);
}
}
function collect(uint256 _amount) onlyController {
if (wallet.send(_amount)) {
LogCollection(wallet, _amount);
} else {
LogCollectionFailure(wallet, _amount);
}
}
}