Version 2 of the Populous per-client deposit contract, extended from ERC20 custody to ether, ERC721 and ERC1155, and stamped with the client ID it belongs to.
Historical Significance
ERC1155 was still a draft when this was deployed, and very little onchain in 2018 was written to hold all three token standards plus ether behind one authorisation check. What makes it readable now is the clientId slot: version 1 deposit contracts were anonymous, identifiable only by which client's records pointed at them, and version 2 put the identifier onchain. The receiver hooks are the other tell. They are the point at which a deposit address stopped being a passive balance and had to actively consent to what was sent to it.
Key Facts
Description
This is the second generation of the address Populous gave each client on its invoice financing platform. The first version held ERC20 tokens and nothing else. This one reports version 2 through getVersion, carries the client's identifier in a bytes32 storage slot readable through getClientId, and widens custody to every asset type the platform had started to touch.
transferEther sends ether out with a balance check and a send, logging EtherTransfer. transferERC721 calls safeTransferFrom on the token contract with this contract as the sender, and transferERC1155 calls safeTransfer. Each one is gated the same way version 1 was, on an AccessManager answering true to isServer or isPopulous, so widening the asset types did not widen who may act.
Because the contract is now a destination for safe transfers, it implements the two receiver hooks: onERC721Received returns 0x150b7a02 and onERC1155Received returns 0xf23a6e61, the magic values those standards require before a token contract will complete a transfer into a contract account. Without them these addresses would have been unable to receive the assets they were built to hold.
The read side follows: balanceOf branches on the zero address to report ether rather than a token balance, and balanceOfERC721 and balanceOfERC1155 query the respective token contracts. The source is Populous's own, DepositContract inheriting withAccessManager against the iERC20Token, ERC721Basic and ERC1155 interfaces.
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.17;
contract iERC20Token {
function transfer(address _to, uint256 _value) public returns (bool success);
function balanceOf(address _owner) public view returns (uint256 balance);
}
contract ERC1155 {
function safeTransfer(address _to, uint256 _id, uint256 _value, bytes _data) external;
function balanceOf(uint256 _id, address _owner) external view returns (uint256);
}
contract ERC721Basic {
function balanceOf(address _owner) public view returns (uint256 _balance);
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes _data) public;
}
contract AccessManager {
function isServer(address sender) public view returns (bool);
function isPopulous(address sender) public view returns (bool);
}
contract withAccessManager {
AccessManager public AM;
modifier onlyServer { require(AM.isServer(msg.sender) == true); _; }
modifier onlyServerOrOnlyPopulous {
require(AM.isServer(msg.sender) == true || AM.isPopulous(msg.sender) == true); _;
}
function withAccessManager(address _accessManager) public { AM = AccessManager(_accessManager); }
function updateAccessManager(address _accessManager) public onlyServer { AM = AccessManager(_accessManager); }
}
contract DepositContract is withAccessManager {
bytes32 public clientId;
uint256 public version = 2;
event EtherTransfer(address to, uint256 value);
function DepositContract(bytes32 _clientId, address accessManager) public withAccessManager(accessManager) {
clientId = _clientId;
}
function transfer(address populousTokenContract, address _to, uint256 _value) public
onlyServerOrOnlyPopulous returns (bool success)
{
return iERC20Token(populousTokenContract).transfer(_to, _value);
}
function transferERC1155(address _erc1155Token, address _to, uint256 _id, uint256 _value)
public onlyServerOrOnlyPopulous returns (bool success) {
ERC1155(_erc1155Token).safeTransfer(_to, _id, _value, "");
return true;
}
function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes _data) public returns(bytes4) {
return 0x150b7a02;
}
function onERC1155Received(address _operator, address _from, uint256 _id, uint256 _value, bytes _data) public returns(bytes4) {
return 0xf23a6e61;
}
function transferERC721(
address erc721Token,
address _to,
uint256 _tokenId
)
public onlyServerOrOnlyPopulous returns (bool success)
{
ERC721Basic(erc721Token).safeTransferFrom(this, _to, _tokenId, "");
return true;
}
function transferEther(address _to, uint256 _value) public
onlyServerOrOnlyPopulous returns (bool success)
{
require(this.balance >= _value);
require(_to.send(_value) == true);
EtherTransfer(_to, _value);
return true;
}
function balanceOf(address populousTokenContract) public view returns (uint256) {
if (populousTokenContract == address(0)) {
return address(this).balance;
} else {
return iERC20Token(populousTokenContract).balanceOf(this);
}
}
function balanceOfERC721(address erc721Token) public view returns (uint256) {
return ERC721Basic(erc721Token).balanceOf(this);
}
function balanceOfERC1155(address erc1155Token, uint256 _id) external view returns (uint256) {
return ERC1155(erc1155Token).balanceOf(_id, this);
}
function getVersion() public view returns (uint256) {
return version;
}
function getClientId() public view returns (bytes32 _clientId) {
return clientId;
}
}External Links
Related contracts
DepositContract
Same deployerVersion 2 of the Populous per-client deposit contract, extended from ERC20 custody to ether, ERC721 and ERC1155, and stamped with the client ID it belongs to.
0x324454...2dc8b3November 25, 2018DepositContract
Same deployerVersion 2 of the Populous per-client deposit contract, extended from ERC20 custody to ether, ERC721 and ERC1155, and stamped with the client ID it belongs to.
0x7fce5a...1f20bfNovember 25, 2018DepositContract
Same deployerVersion 2 of the Populous per-client deposit contract, extended from ERC20 custody to ether, ERC721 and ERC1155, and stamped with the client ID it belongs to.
0x2a6d4b...f96028November 25, 2018DepositContract
Same deployerVersion 2 of the Populous per-client deposit contract, extended from ERC20 custody to ether, ERC721 and ERC1155, and stamped with the client ID it belongs to.
0xa35378...619cb9November 25, 2018DepositContract
Same deployerVersion 2 of the Populous per-client deposit contract, extended from ERC20 custody to ether, ERC721 and ERC1155, and stamped with the client ID it belongs to.
0xabc3bf...e565d6November 25, 2018DepositContract
Same deployerVersion 2 of the Populous per-client deposit contract, extended from ERC20 custody to ether, ERC721 and ERC1155, and stamped with the client ID it belongs to.
0x566058...fa9e07November 25, 2018