Wallet

This wallet contract is capable of receiving, holding and sending Ether as well as tokens that comply with one of the following standards:

Implementation in Vyper

Truffle Project

Contract

Tests

Deploying

The wallet contract accesses the ERC1820Registry contract in its constructor. It is therefore necessary that the ERC1820Registry contract exists on the (test) network to where the wallet contract gets deployed.

In migrations/1_initial_migration.js a check is performed to determine if the ERC1820Registry contract exists - if it doesn't it is deployed.

wallet.vy
# Author: Sören Steiger, twitter.com/ssteiger_
# License: MIT

contract ERC1820Registry:
    def setInterfaceImplementer(
        _addr: address,
        _interfaceHash: bytes32,
        _implementer: address
    ): modifying

contract ERC20Token:
    def transfer(
        _to: address,
        _value: uint256
    ) -> bool: modifying

contract ERC721Token:
    def safeTransferFrom(
        _from: address,
        _to: address,
        _tokenId: uint256,
        _data: bytes[256]
    ): modifying

contract ERC777Token:
    def send(
        _to: address,
        _amount: uint256,
        _data: bytes[256]
    ): modifying


ETHReceived: event({
    _from: address,
    _amount: wei_value
})

ETHSent: event({
    _to: address,
    _amount: uint256
})

# TODO:
#ERC20Received: event({
#})

ERC20Sent: event({
    _token: address,
    _to: address,
    _amount: uint256
})

ERC721Received: event({
    _token: address,
    _from: address,
    _tokenId: uint256,
    _data: bytes32
})

ERC721Sent: event({
    _token: address,
    _from: address,
    _to: address,
    _tokenId: uint256,
    _data: bytes[256]
})

ERC777Received: event({
    _operator: indexed(address),
    _from: indexed(address),
    _to: indexed(address),
    _amount: uint256,
    _data: bytes[256],
    _operatorData: bytes[256]
})

ERC777Sent: event({
    _operator: indexed(address),
    _from: indexed(address),
    _to: indexed(address),
    _amount: uint256,
    _data: bytes[256],
    _operatorData: bytes[256]
})


erc1820Registry: ERC1820Registry
erc1820RegistryAddress: constant(address) = 0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24

owner: public(address)


@public
def __init__():
    self.owner = msg.sender
    self.erc1820Registry = ERC1820Registry(erc1820RegistryAddress)
    self.erc1820Registry.setInterfaceImplementer(self, keccak256("ERC777TokensRecipient"), self)
    self.erc1820Registry.setInterfaceImplementer(self, keccak256("ERC777TokensSender"), self)


# ----- ETH -----
@public
@payable
def __default__():
    log.ETHReceived(msg.sender, msg.value)

@public
def sendETH(
    _to: address,
    _amount: uint256
  ):
    assert msg.sender == self.owner
    send(_to, _amount)
    log.ETHSent(_to, _amount)


# ----- ERC20 -----
@public
def sendERC20(
    _token: address,
    _to: address,
    _amount: uint256
  ):
    assert msg.sender == self.owner
    ERC20Token(_token).transfer(_to, _amount)
    log.ERC20Sent(_token, _to, _amount)

#@public
#def onERC20Received():


# ----- ERC721 -----
@public
def sendERC721(
    _token: address,
    _to: address,
    _tokenId: uint256,
    _data: bytes[256]=""
  ):
    assert msg.sender == self.owner
    ERC721Token(_token).safeTransferFrom(self, _to, _tokenId, _data)
    log.ERC721Sent(_token, self, _to, _tokenId, _data)

@public
def onERC721Received(
    _token: address,
    _from: address,
    _tokenId: uint256,
    _data: bytes32
  ) -> bytes32:
    log.ERC721Received(_token, _from, _tokenId, _data)
    # TODO: need to return bytes4
    return keccak256("onERC721Received(address,address,uint256,bytes)")


# ----- ERC777 -----
@public
def sendERC777(
    _token: address,
    _to: address,
    _amount: uint256,
    _data: bytes[256]=""
  ):
    assert msg.sender == self.owner
    ERC777Token(_token).send(_to, _amount, _data)

@public
def tokensToSend(
    _operator: address,
    _from: address,
    _to: address,
    _amount: uint256,
    _data: bytes[256],
    _operatorData: bytes[256]
  ):
    log.ERC777Sent(_operator, _from, _to, _amount, _data, _operatorData)

@public
def tokensReceived(
    _operator: address,
    _from: address,
    _to: address,
    _amount: uint256,
    _data: bytes[256],
    _operatorData: bytes[256]
  ):
    log.ERC777Received(_operator, _from, _to, _amount, _data, _operatorData)

Last updated