ETH Price: $2,149.74 (+5.22%)

Transaction Decoder

Block:
10208699 at Jun-05-2020 11:25:53 PM +UTC
Transaction Fee:
0.00140381999993619 ETH $3.02
Gas Used:
63,810 Gas / 21.999999999 Gwei

Emitted Events:

127 Statera.Transfer( from=[Receiver] 0x2347a7ca98ab11a830279f480362d0b24d9d20fe, to=Vyper_contract, value=5511757287267895349552 )
128 Statera.Transfer( from=[Receiver] 0x2347a7ca98ab11a830279f480362d0b24d9d20fe, to=0x0000000000000000000000000000000000000000, value=55674316033009043935 )
129 Vyper_contract.EthPurchase( buyer=[Receiver] 0x2347a7ca98ab11a830279f480362d0b24d9d20fe, tokens_sold=5567431603300904393487, eth_bought=2465120141685535972 )

Account State Difference:

  Address   Before After State Difference Code
0x00000000...438691c04
0x2347a7cA...24d9d20Fe 33.056524389770211051 Eth35.521644531455747023 Eth2.465120141685535972
0x38f6074a...76A402073
0 Eth
Nonce: 0
0 Eth
Nonce: 0
From: 0 To: 0
0x6AE23C5E...ff4D5695d 533.044746094369913146 Eth530.579625952684377174 Eth2.465120141685535972
0x6f136310...Db7dd95Cf
0 Eth
Nonce: 0
0 Eth
Nonce: 0
From: 0 To: 0
0x7D9D97df...D514261e0
3.00561939117175318 Eth
Nonce: 592
3.00421557117181699 Eth
Nonce: 593
0.00140381999993619
(F2Pool Old)
3,812.175426620504019573 Eth3,812.176830440503955763 Eth0.00140381999993619
0xa7DE0873...Abe3DeED1
0xD356Da4c...4DDFD9429
0 Eth
Nonce: 0
0 Eth
Nonce: 0
From: 0 To: 0

Execution Trace

0x2347a7ca98ab11a830279f480362d0b24d9d20fe.0ae51761( )
  • Statera.balanceOf( owner=0x2347a7cA98Ab11a830279f480362d0b24d9d20Fe ) => ( 5567431603300904393487 )
  • Statera.allowance( owner=0x2347a7cA98Ab11a830279f480362d0b24d9d20Fe, spender=0x6AE23C5EDaad107026a3Dabb74396e1ff4D5695d ) => ( 115792089237316195423570985008687907853269984665640562509214367232916785062602 )
  • Vyper_contract.tokenToEthSwapInput( tokens_sold=5567431603300904393487, min_eth=1, deadline=1591399553 ) => ( out=2465120141685535972 )
    • Vyper_contract.tokenToEthSwapInput( tokens_sold=5567431603300904393487, min_eth=1, deadline=1591399553 ) => ( out=2465120141685535972 )
      • Statera.balanceOf( owner=0x6AE23C5EDaad107026a3Dabb74396e1ff4D5695d ) => ( 1194710079424376965940331 )
      • ETH 2.465120141685535972 0x2347a7ca98ab11a830279f480362d0b24d9d20fe.CALL( )
      • Statera.transferFrom( from=0x2347a7cA98Ab11a830279f480362d0b24d9d20Fe, to=0x6AE23C5EDaad107026a3Dabb74396e1ff4D5695d, value=5567431603300904393487 ) => ( True )
      • GasToken2.freeFromUpTo( from=0x000000006cc74a85F3bBea90b2b6C453CBED90B3, value=3 ) => ( freed=3 )
        • 0x38f6074a3b953da2fc661f7b1d1430a76a402073.CALL( )
          • GasToken2.SELFDESTRUCT( )
          • 0x6f1363103aa12d303c4911f7aa1dc0adb7dd95cf.CALL( )
            • GasToken2.SELFDESTRUCT( )
            • 0xd356da4c8fde8d9e423781c74ac440a4ddfd9429.CALL( )
              • GasToken2.SELFDESTRUCT( )
                File 1 of 4: Vyper_contract
                # @title Uniswap Exchange Interface V1
                # @notice Source code found at https://github.com/uniswap
                # @notice Use at your own risk
                
                contract Factory():
                    def getExchange(token_addr: address) -> address: constant
                
                contract Exchange():
                    def getEthToTokenOutputPrice(tokens_bought: uint256) -> uint256(wei): constant
                    def ethToTokenTransferInput(min_tokens: uint256, deadline: timestamp, recipient: address) -> uint256: modifying
                    def ethToTokenTransferOutput(tokens_bought: uint256, deadline: timestamp, recipient: address) -> uint256(wei): modifying
                
                TokenPurchase: event({buyer: indexed(address), eth_sold: indexed(uint256(wei)), tokens_bought: indexed(uint256)})
                EthPurchase: event({buyer: indexed(address), tokens_sold: indexed(uint256), eth_bought: indexed(uint256(wei))})
                AddLiquidity: event({provider: indexed(address), eth_amount: indexed(uint256(wei)), token_amount: indexed(uint256)})
                RemoveLiquidity: event({provider: indexed(address), eth_amount: indexed(uint256(wei)), token_amount: indexed(uint256)})
                Transfer: event({_from: indexed(address), _to: indexed(address), _value: uint256})
                Approval: event({_owner: indexed(address), _spender: indexed(address), _value: uint256})
                
                name: public(bytes32)                             # Uniswap V1
                symbol: public(bytes32)                           # UNI-V1
                decimals: public(uint256)                         # 18
                totalSupply: public(uint256)                      # total number of UNI in existence
                balances: uint256[address]                        # UNI balance of an address
                allowances: (uint256[address])[address]           # UNI allowance of one address on another
                token: address(ERC20)                             # address of the ERC20 token traded on this contract
                factory: Factory                                  # interface for the factory that created this contract
                
                # @dev This function acts as a contract constructor which is not currently supported in contracts deployed
                #      using create_with_code_of(). It is called once by the factory during contract creation.
                @public
                def setup(token_addr: address):
                    assert (self.factory == ZERO_ADDRESS and self.token == ZERO_ADDRESS) and token_addr != ZERO_ADDRESS
                    self.factory = msg.sender
                    self.token = token_addr
                    self.name = 0x556e697377617020563100000000000000000000000000000000000000000000
                    self.symbol = 0x554e492d56310000000000000000000000000000000000000000000000000000
                    self.decimals = 18
                
                # @notice Deposit ETH and Tokens (self.token) at current ratio to mint UNI tokens.
                # @dev min_liquidity does nothing when total UNI supply is 0.
                # @param min_liquidity Minimum number of UNI sender will mint if total UNI supply is greater than 0.
                # @param max_tokens Maximum number of tokens deposited. Deposits max amount if total UNI supply is 0.
                # @param deadline Time after which this transaction can no longer be executed.
                # @return The amount of UNI minted.
                @public
                @payable
                def addLiquidity(min_liquidity: uint256, max_tokens: uint256, deadline: timestamp) -> uint256:
                    assert deadline > block.timestamp and (max_tokens > 0 and msg.value > 0)
                    total_liquidity: uint256 = self.totalSupply
                    if total_liquidity > 0:
                        assert min_liquidity > 0
                        eth_reserve: uint256(wei) = self.balance - msg.value
                        token_reserve: uint256 = self.token.balanceOf(self)
                        token_amount: uint256 = msg.value * token_reserve / eth_reserve + 1
                        liquidity_minted: uint256 = msg.value * total_liquidity / eth_reserve
                        assert max_tokens >= token_amount and liquidity_minted >= min_liquidity
                        self.balances[msg.sender] += liquidity_minted
                        self.totalSupply = total_liquidity + liquidity_minted
                        assert self.token.transferFrom(msg.sender, self, token_amount)
                        log.AddLiquidity(msg.sender, msg.value, token_amount)
                        log.Transfer(ZERO_ADDRESS, msg.sender, liquidity_minted)
                        return liquidity_minted
                    else:
                        assert (self.factory != ZERO_ADDRESS and self.token != ZERO_ADDRESS) and msg.value >= 1000000000
                        assert self.factory.getExchange(self.token) == self
                        token_amount: uint256 = max_tokens
                        initial_liquidity: uint256 = as_unitless_number(self.balance)
                        self.totalSupply = initial_liquidity
                        self.balances[msg.sender] = initial_liquidity
                        assert self.token.transferFrom(msg.sender, self, token_amount)
                        log.AddLiquidity(msg.sender, msg.value, token_amount)
                        log.Transfer(ZERO_ADDRESS, msg.sender, initial_liquidity)
                        return initial_liquidity
                
                # @dev Burn UNI tokens to withdraw ETH and Tokens at current ratio.
                # @param amount Amount of UNI burned.
                # @param min_eth Minimum ETH withdrawn.
                # @param min_tokens Minimum Tokens withdrawn.
                # @param deadline Time after which this transaction can no longer be executed.
                # @return The amount of ETH and Tokens withdrawn.
                @public
                def removeLiquidity(amount: uint256, min_eth: uint256(wei), min_tokens: uint256, deadline: timestamp) -> (uint256(wei), uint256):
                    assert (amount > 0 and deadline > block.timestamp) and (min_eth > 0 and min_tokens > 0)
                    total_liquidity: uint256 = self.totalSupply
                    assert total_liquidity > 0
                    token_reserve: uint256 = self.token.balanceOf(self)
                    eth_amount: uint256(wei) = amount * self.balance / total_liquidity
                    token_amount: uint256 = amount * token_reserve / total_liquidity
                    assert eth_amount >= min_eth and token_amount >= min_tokens
                    self.balances[msg.sender] -= amount
                    self.totalSupply = total_liquidity - amount
                    send(msg.sender, eth_amount)
                    assert self.token.transfer(msg.sender, token_amount)
                    log.RemoveLiquidity(msg.sender, eth_amount, token_amount)
                    log.Transfer(msg.sender, ZERO_ADDRESS, amount)
                    return eth_amount, token_amount
                
                # @dev Pricing function for converting between ETH and Tokens.
                # @param input_amount Amount of ETH or Tokens being sold.
                # @param input_reserve Amount of ETH or Tokens (input type) in exchange reserves.
                # @param output_reserve Amount of ETH or Tokens (output type) in exchange reserves.
                # @return Amount of ETH or Tokens bought.
                @private
                @constant
                def getInputPrice(input_amount: uint256, input_reserve: uint256, output_reserve: uint256) -> uint256:
                    assert input_reserve > 0 and output_reserve > 0
                    input_amount_with_fee: uint256 = input_amount * 997
                    numerator: uint256 = input_amount_with_fee * output_reserve
                    denominator: uint256 = (input_reserve * 1000) + input_amount_with_fee
                    return numerator / denominator
                
                # @dev Pricing function for converting between ETH and Tokens.
                # @param output_amount Amount of ETH or Tokens being bought.
                # @param input_reserve Amount of ETH or Tokens (input type) in exchange reserves.
                # @param output_reserve Amount of ETH or Tokens (output type) in exchange reserves.
                # @return Amount of ETH or Tokens sold.
                @private
                @constant
                def getOutputPrice(output_amount: uint256, input_reserve: uint256, output_reserve: uint256) -> uint256:
                    assert input_reserve > 0 and output_reserve > 0
                    numerator: uint256 = input_reserve * output_amount * 1000
                    denominator: uint256 = (output_reserve - output_amount) * 997
                    return numerator / denominator + 1
                
                @private
                def ethToTokenInput(eth_sold: uint256(wei), min_tokens: uint256, deadline: timestamp, buyer: address, recipient: address) -> uint256:
                    assert deadline >= block.timestamp and (eth_sold > 0 and min_tokens > 0)
                    token_reserve: uint256 = self.token.balanceOf(self)
                    tokens_bought: uint256 = self.getInputPrice(as_unitless_number(eth_sold), as_unitless_number(self.balance - eth_sold), token_reserve)
                    assert tokens_bought >= min_tokens
                    assert self.token.transfer(recipient, tokens_bought)
                    log.TokenPurchase(buyer, eth_sold, tokens_bought)
                    return tokens_bought
                
                # @notice Convert ETH to Tokens.
                # @dev User specifies exact input (msg.value).
                # @dev User cannot specify minimum output or deadline.
                @public
                @payable
                def __default__():
                    self.ethToTokenInput(msg.value, 1, block.timestamp, msg.sender, msg.sender)
                
                # @notice Convert ETH to Tokens.
                # @dev User specifies exact input (msg.value) and minimum output.
                # @param min_tokens Minimum Tokens bought.
                # @param deadline Time after which this transaction can no longer be executed.
                # @return Amount of Tokens bought.
                @public
                @payable
                def ethToTokenSwapInput(min_tokens: uint256, deadline: timestamp) -> uint256:
                    return self.ethToTokenInput(msg.value, min_tokens, deadline, msg.sender, msg.sender)
                
                # @notice Convert ETH to Tokens and transfers Tokens to recipient.
                # @dev User specifies exact input (msg.value) and minimum output
                # @param min_tokens Minimum Tokens bought.
                # @param deadline Time after which this transaction can no longer be executed.
                # @param recipient The address that receives output Tokens.
                # @return Amount of Tokens bought.
                @public
                @payable
                def ethToTokenTransferInput(min_tokens: uint256, deadline: timestamp, recipient: address) -> uint256:
                    assert recipient != self and recipient != ZERO_ADDRESS
                    return self.ethToTokenInput(msg.value, min_tokens, deadline, msg.sender, recipient)
                
                @private
                def ethToTokenOutput(tokens_bought: uint256, max_eth: uint256(wei), deadline: timestamp, buyer: address, recipient: address) -> uint256(wei):
                    assert deadline >= block.timestamp and (tokens_bought > 0 and max_eth > 0)
                    token_reserve: uint256 = self.token.balanceOf(self)
                    eth_sold: uint256 = self.getOutputPrice(tokens_bought, as_unitless_number(self.balance - max_eth), token_reserve)
                    # Throws if eth_sold > max_eth
                    eth_refund: uint256(wei) = max_eth - as_wei_value(eth_sold, 'wei')
                    if eth_refund > 0:
                        send(buyer, eth_refund)
                    assert self.token.transfer(recipient, tokens_bought)
                    log.TokenPurchase(buyer, as_wei_value(eth_sold, 'wei'), tokens_bought)
                    return as_wei_value(eth_sold, 'wei')
                
                # @notice Convert ETH to Tokens.
                # @dev User specifies maximum input (msg.value) and exact output.
                # @param tokens_bought Amount of tokens bought.
                # @param deadline Time after which this transaction can no longer be executed.
                # @return Amount of ETH sold.
                @public
                @payable
                def ethToTokenSwapOutput(tokens_bought: uint256, deadline: timestamp) -> uint256(wei):
                    return self.ethToTokenOutput(tokens_bought, msg.value, deadline, msg.sender, msg.sender)
                
                # @notice Convert ETH to Tokens and transfers Tokens to recipient.
                # @dev User specifies maximum input (msg.value) and exact output.
                # @param tokens_bought Amount of tokens bought.
                # @param deadline Time after which this transaction can no longer be executed.
                # @param recipient The address that receives output Tokens.
                # @return Amount of ETH sold.
                @public
                @payable
                def ethToTokenTransferOutput(tokens_bought: uint256, deadline: timestamp, recipient: address) -> uint256(wei):
                    assert recipient != self and recipient != ZERO_ADDRESS
                    return self.ethToTokenOutput(tokens_bought, msg.value, deadline, msg.sender, recipient)
                
                @private
                def tokenToEthInput(tokens_sold: uint256, min_eth: uint256(wei), deadline: timestamp, buyer: address, recipient: address) -> uint256(wei):
                    assert deadline >= block.timestamp and (tokens_sold > 0 and min_eth > 0)
                    token_reserve: uint256 = self.token.balanceOf(self)
                    eth_bought: uint256 = self.getInputPrice(tokens_sold, token_reserve, as_unitless_number(self.balance))
                    wei_bought: uint256(wei) = as_wei_value(eth_bought, 'wei')
                    assert wei_bought >= min_eth
                    send(recipient, wei_bought)
                    assert self.token.transferFrom(buyer, self, tokens_sold)
                    log.EthPurchase(buyer, tokens_sold, wei_bought)
                    return wei_bought
                
                
                # @notice Convert Tokens to ETH.
                # @dev User specifies exact input and minimum output.
                # @param tokens_sold Amount of Tokens sold.
                # @param min_eth Minimum ETH purchased.
                # @param deadline Time after which this transaction can no longer be executed.
                # @return Amount of ETH bought.
                @public
                def tokenToEthSwapInput(tokens_sold: uint256, min_eth: uint256(wei), deadline: timestamp) -> uint256(wei):
                    return self.tokenToEthInput(tokens_sold, min_eth, deadline, msg.sender, msg.sender)
                
                # @notice Convert Tokens to ETH and transfers ETH to recipient.
                # @dev User specifies exact input and minimum output.
                # @param tokens_sold Amount of Tokens sold.
                # @param min_eth Minimum ETH purchased.
                # @param deadline Time after which this transaction can no longer be executed.
                # @param recipient The address that receives output ETH.
                # @return Amount of ETH bought.
                @public
                def tokenToEthTransferInput(tokens_sold: uint256, min_eth: uint256(wei), deadline: timestamp, recipient: address) -> uint256(wei):
                    assert recipient != self and recipient != ZERO_ADDRESS
                    return self.tokenToEthInput(tokens_sold, min_eth, deadline, msg.sender, recipient)
                
                @private
                def tokenToEthOutput(eth_bought: uint256(wei), max_tokens: uint256, deadline: timestamp, buyer: address, recipient: address) -> uint256:
                    assert deadline >= block.timestamp and eth_bought > 0
                    token_reserve: uint256 = self.token.balanceOf(self)
                    tokens_sold: uint256 = self.getOutputPrice(as_unitless_number(eth_bought), token_reserve, as_unitless_number(self.balance))
                    # tokens sold is always > 0
                    assert max_tokens >= tokens_sold
                    send(recipient, eth_bought)
                    assert self.token.transferFrom(buyer, self, tokens_sold)
                    log.EthPurchase(buyer, tokens_sold, eth_bought)
                    return tokens_sold
                
                # @notice Convert Tokens to ETH.
                # @dev User specifies maximum input and exact output.
                # @param eth_bought Amount of ETH purchased.
                # @param max_tokens Maximum Tokens sold.
                # @param deadline Time after which this transaction can no longer be executed.
                # @return Amount of Tokens sold.
                @public
                def tokenToEthSwapOutput(eth_bought: uint256(wei), max_tokens: uint256, deadline: timestamp) -> uint256:
                    return self.tokenToEthOutput(eth_bought, max_tokens, deadline, msg.sender, msg.sender)
                
                # @notice Convert Tokens to ETH and transfers ETH to recipient.
                # @dev User specifies maximum input and exact output.
                # @param eth_bought Amount of ETH purchased.
                # @param max_tokens Maximum Tokens sold.
                # @param deadline Time after which this transaction can no longer be executed.
                # @param recipient The address that receives output ETH.
                # @return Amount of Tokens sold.
                @public
                def tokenToEthTransferOutput(eth_bought: uint256(wei), max_tokens: uint256, deadline: timestamp, recipient: address) -> uint256:
                    assert recipient != self and recipient != ZERO_ADDRESS
                    return self.tokenToEthOutput(eth_bought, max_tokens, deadline, msg.sender, recipient)
                
                @private
                def tokenToTokenInput(tokens_sold: uint256, min_tokens_bought: uint256, min_eth_bought: uint256(wei), deadline: timestamp, buyer: address, recipient: address, exchange_addr: address) -> uint256:
                    assert (deadline >= block.timestamp and tokens_sold > 0) and (min_tokens_bought > 0 and min_eth_bought > 0)
                    assert exchange_addr != self and exchange_addr != ZERO_ADDRESS
                    token_reserve: uint256 = self.token.balanceOf(self)
                    eth_bought: uint256 = self.getInputPrice(tokens_sold, token_reserve, as_unitless_number(self.balance))
                    wei_bought: uint256(wei) = as_wei_value(eth_bought, 'wei')
                    assert wei_bought >= min_eth_bought
                    assert self.token.transferFrom(buyer, self, tokens_sold)
                    tokens_bought: uint256 = Exchange(exchange_addr).ethToTokenTransferInput(min_tokens_bought, deadline, recipient, value=wei_bought)
                    log.EthPurchase(buyer, tokens_sold, wei_bought)
                    return tokens_bought
                
                # @notice Convert Tokens (self.token) to Tokens (token_addr).
                # @dev User specifies exact input and minimum output.
                # @param tokens_sold Amount of Tokens sold.
                # @param min_tokens_bought Minimum Tokens (token_addr) purchased.
                # @param min_eth_bought Minimum ETH purchased as intermediary.
                # @param deadline Time after which this transaction can no longer be executed.
                # @param token_addr The address of the token being purchased.
                # @return Amount of Tokens (token_addr) bought.
                @public
                def tokenToTokenSwapInput(tokens_sold: uint256, min_tokens_bought: uint256, min_eth_bought: uint256(wei), deadline: timestamp, token_addr: address) -> uint256:
                    exchange_addr: address = self.factory.getExchange(token_addr)
                    return self.tokenToTokenInput(tokens_sold, min_tokens_bought, min_eth_bought, deadline, msg.sender, msg.sender, exchange_addr)
                
                # @notice Convert Tokens (self.token) to Tokens (token_addr) and transfers
                #         Tokens (token_addr) to recipient.
                # @dev User specifies exact input and minimum output.
                # @param tokens_sold Amount of Tokens sold.
                # @param min_tokens_bought Minimum Tokens (token_addr) purchased.
                # @param min_eth_bought Minimum ETH purchased as intermediary.
                # @param deadline Time after which this transaction can no longer be executed.
                # @param recipient The address that receives output ETH.
                # @param token_addr The address of the token being purchased.
                # @return Amount of Tokens (token_addr) bought.
                @public
                def tokenToTokenTransferInput(tokens_sold: uint256, min_tokens_bought: uint256, min_eth_bought: uint256(wei), deadline: timestamp, recipient: address, token_addr: address) -> uint256:
                    exchange_addr: address = self.factory.getExchange(token_addr)
                    return self.tokenToTokenInput(tokens_sold, min_tokens_bought, min_eth_bought, deadline, msg.sender, recipient, exchange_addr)
                
                @private
                def tokenToTokenOutput(tokens_bought: uint256, max_tokens_sold: uint256, max_eth_sold: uint256(wei), deadline: timestamp, buyer: address, recipient: address, exchange_addr: address) -> uint256:
                    assert deadline >= block.timestamp and (tokens_bought > 0 and max_eth_sold > 0)
                    assert exchange_addr != self and exchange_addr != ZERO_ADDRESS
                    eth_bought: uint256(wei) = Exchange(exchange_addr).getEthToTokenOutputPrice(tokens_bought)
                    token_reserve: uint256 = self.token.balanceOf(self)
                    tokens_sold: uint256 = self.getOutputPrice(as_unitless_number(eth_bought), token_reserve, as_unitless_number(self.balance))
                    # tokens sold is always > 0
                    assert max_tokens_sold >= tokens_sold and max_eth_sold >= eth_bought
                    assert self.token.transferFrom(buyer, self, tokens_sold)
                    eth_sold: uint256(wei) = Exchange(exchange_addr).ethToTokenTransferOutput(tokens_bought, deadline, recipient, value=eth_bought)
                    log.EthPurchase(buyer, tokens_sold, eth_bought)
                    return tokens_sold
                
                # @notice Convert Tokens (self.token) to Tokens (token_addr).
                # @dev User specifies maximum input and exact output.
                # @param tokens_bought Amount of Tokens (token_addr) bought.
                # @param max_tokens_sold Maximum Tokens (self.token) sold.
                # @param max_eth_sold Maximum ETH purchased as intermediary.
                # @param deadline Time after which this transaction can no longer be executed.
                # @param token_addr The address of the token being purchased.
                # @return Amount of Tokens (self.token) sold.
                @public
                def tokenToTokenSwapOutput(tokens_bought: uint256, max_tokens_sold: uint256, max_eth_sold: uint256(wei), deadline: timestamp, token_addr: address) -> uint256:
                    exchange_addr: address = self.factory.getExchange(token_addr)
                    return self.tokenToTokenOutput(tokens_bought, max_tokens_sold, max_eth_sold, deadline, msg.sender, msg.sender, exchange_addr)
                
                # @notice Convert Tokens (self.token) to Tokens (token_addr) and transfers
                #         Tokens (token_addr) to recipient.
                # @dev User specifies maximum input and exact output.
                # @param tokens_bought Amount of Tokens (token_addr) bought.
                # @param max_tokens_sold Maximum Tokens (self.token) sold.
                # @param max_eth_sold Maximum ETH purchased as intermediary.
                # @param deadline Time after which this transaction can no longer be executed.
                # @param recipient The address that receives output ETH.
                # @param token_addr The address of the token being purchased.
                # @return Amount of Tokens (self.token) sold.
                @public
                def tokenToTokenTransferOutput(tokens_bought: uint256, max_tokens_sold: uint256, max_eth_sold: uint256(wei), deadline: timestamp, recipient: address, token_addr: address) -> uint256:
                    exchange_addr: address = self.factory.getExchange(token_addr)
                    return self.tokenToTokenOutput(tokens_bought, max_tokens_sold, max_eth_sold, deadline, msg.sender, recipient, exchange_addr)
                
                # @notice Convert Tokens (self.token) to Tokens (exchange_addr.token).
                # @dev Allows trades through contracts that were not deployed from the same factory.
                # @dev User specifies exact input and minimum output.
                # @param tokens_sold Amount of Tokens sold.
                # @param min_tokens_bought Minimum Tokens (token_addr) purchased.
                # @param min_eth_bought Minimum ETH purchased as intermediary.
                # @param deadline Time after which this transaction can no longer be executed.
                # @param exchange_addr The address of the exchange for the token being purchased.
                # @return Amount of Tokens (exchange_addr.token) bought.
                @public
                def tokenToExchangeSwapInput(tokens_sold: uint256, min_tokens_bought: uint256, min_eth_bought: uint256(wei), deadline: timestamp, exchange_addr: address) -> uint256:
                    return self.tokenToTokenInput(tokens_sold, min_tokens_bought, min_eth_bought, deadline, msg.sender, msg.sender, exchange_addr)
                
                # @notice Convert Tokens (self.token) to Tokens (exchange_addr.token) and transfers
                #         Tokens (exchange_addr.token) to recipient.
                # @dev Allows trades through contracts that were not deployed from the same factory.
                # @dev User specifies exact input and minimum output.
                # @param tokens_sold Amount of Tokens sold.
                # @param min_tokens_bought Minimum Tokens (token_addr) purchased.
                # @param min_eth_bought Minimum ETH purchased as intermediary.
                # @param deadline Time after which this transaction can no longer be executed.
                # @param recipient The address that receives output ETH.
                # @param exchange_addr The address of the exchange for the token being purchased.
                # @return Amount of Tokens (exchange_addr.token) bought.
                @public
                def tokenToExchangeTransferInput(tokens_sold: uint256, min_tokens_bought: uint256, min_eth_bought: uint256(wei), deadline: timestamp, recipient: address, exchange_addr: address) -> uint256:
                    assert recipient != self
                    return self.tokenToTokenInput(tokens_sold, min_tokens_bought, min_eth_bought, deadline, msg.sender, recipient, exchange_addr)
                
                # @notice Convert Tokens (self.token) to Tokens (exchange_addr.token).
                # @dev Allows trades through contracts that were not deployed from the same factory.
                # @dev User specifies maximum input and exact output.
                # @param tokens_bought Amount of Tokens (token_addr) bought.
                # @param max_tokens_sold Maximum Tokens (self.token) sold.
                # @param max_eth_sold Maximum ETH purchased as intermediary.
                # @param deadline Time after which this transaction can no longer be executed.
                # @param exchange_addr The address of the exchange for the token being purchased.
                # @return Amount of Tokens (self.token) sold.
                @public
                def tokenToExchangeSwapOutput(tokens_bought: uint256, max_tokens_sold: uint256, max_eth_sold: uint256(wei), deadline: timestamp, exchange_addr: address) -> uint256:
                    return self.tokenToTokenOutput(tokens_bought, max_tokens_sold, max_eth_sold, deadline, msg.sender, msg.sender, exchange_addr)
                
                # @notice Convert Tokens (self.token) to Tokens (exchange_addr.token) and transfers
                #         Tokens (exchange_addr.token) to recipient.
                # @dev Allows trades through contracts that were not deployed from the same factory.
                # @dev User specifies maximum input and exact output.
                # @param tokens_bought Amount of Tokens (token_addr) bought.
                # @param max_tokens_sold Maximum Tokens (self.token) sold.
                # @param max_eth_sold Maximum ETH purchased as intermediary.
                # @param deadline Time after which this transaction can no longer be executed.
                # @param recipient The address that receives output ETH.
                # @param token_addr The address of the token being purchased.
                # @return Amount of Tokens (self.token) sold.
                @public
                def tokenToExchangeTransferOutput(tokens_bought: uint256, max_tokens_sold: uint256, max_eth_sold: uint256(wei), deadline: timestamp, recipient: address, exchange_addr: address) -> uint256:
                    assert recipient != self
                    return self.tokenToTokenOutput(tokens_bought, max_tokens_sold, max_eth_sold, deadline, msg.sender, recipient, exchange_addr)
                
                # @notice Public price function for ETH to Token trades with an exact input.
                # @param eth_sold Amount of ETH sold.
                # @return Amount of Tokens that can be bought with input ETH.
                @public
                @constant
                def getEthToTokenInputPrice(eth_sold: uint256(wei)) -> uint256:
                    assert eth_sold > 0
                    token_reserve: uint256 = self.token.balanceOf(self)
                    return self.getInputPrice(as_unitless_number(eth_sold), as_unitless_number(self.balance), token_reserve)
                
                # @notice Public price function for ETH to Token trades with an exact output.
                # @param tokens_bought Amount of Tokens bought.
                # @return Amount of ETH needed to buy output Tokens.
                @public
                @constant
                def getEthToTokenOutputPrice(tokens_bought: uint256) -> uint256(wei):
                    assert tokens_bought > 0
                    token_reserve: uint256 = self.token.balanceOf(self)
                    eth_sold: uint256 = self.getOutputPrice(tokens_bought, as_unitless_number(self.balance), token_reserve)
                    return as_wei_value(eth_sold, 'wei')
                
                # @notice Public price function for Token to ETH trades with an exact input.
                # @param tokens_sold Amount of Tokens sold.
                # @return Amount of ETH that can be bought with input Tokens.
                @public
                @constant
                def getTokenToEthInputPrice(tokens_sold: uint256) -> uint256(wei):
                    assert tokens_sold > 0
                    token_reserve: uint256 = self.token.balanceOf(self)
                    eth_bought: uint256 = self.getInputPrice(tokens_sold, token_reserve, as_unitless_number(self.balance))
                    return as_wei_value(eth_bought, 'wei')
                
                # @notice Public price function for Token to ETH trades with an exact output.
                # @param eth_bought Amount of output ETH.
                # @return Amount of Tokens needed to buy output ETH.
                @public
                @constant
                def getTokenToEthOutputPrice(eth_bought: uint256(wei)) -> uint256:
                    assert eth_bought > 0
                    token_reserve: uint256 = self.token.balanceOf(self)
                    return self.getOutputPrice(as_unitless_number(eth_bought), token_reserve, as_unitless_number(self.balance))
                
                # @return Address of Token that is sold on this exchange.
                @public
                @constant
                def tokenAddress() -> address:
                    return self.token
                
                # @return Address of factory that created this exchange.
                @public
                @constant
                def factoryAddress() -> address(Factory):
                    return self.factory
                
                # ERC20 compatibility for exchange liquidity modified from
                # https://github.com/ethereum/vyper/blob/master/examples/tokens/ERC20.vy
                @public
                @constant
                def balanceOf(_owner : address) -> uint256:
                    return self.balances[_owner]
                
                @public
                def transfer(_to : address, _value : uint256) -> bool:
                    self.balances[msg.sender] -= _value
                    self.balances[_to] += _value
                    log.Transfer(msg.sender, _to, _value)
                    return True
                
                @public
                def transferFrom(_from : address, _to : address, _value : uint256) -> bool:
                    self.balances[_from] -= _value
                    self.balances[_to] += _value
                    self.allowances[_from][msg.sender] -= _value
                    log.Transfer(_from, _to, _value)
                    return True
                
                @public
                def approve(_spender : address, _value : uint256) -> bool:
                    self.allowances[msg.sender][_spender] = _value
                    log.Approval(msg.sender, _spender, _value)
                    return True
                
                @public
                @constant
                def allowance(_owner : address, _spender : address) -> uint256:
                    return self.allowances[_owner][_spender]

                File 2 of 4: Statera
                /*
                *  statera.sol
                *  STA V3 deflationary index token smart contract
                *  2020-05-29
                **/
                
                interface IERC20 {
                  function totalSupply() external view returns (uint256);
                  function balanceOf(address who) external view returns (uint256);
                  function allowance(address owner, address spender) external view returns (uint256);
                  function transfer(address to, uint256 value) external returns (bool);
                  function approve(address spender, uint256 value) external returns (bool);
                  function transferFrom(address from, address to, uint256 value) external returns (bool);
                
                  event Transfer(address indexed from, address indexed to, uint256 value);
                  event Approval(address indexed owner, address indexed spender, uint256 value);
                }
                
                library SafeMath {
                  function mul(uint256 a, uint256 b) internal pure returns (uint256) {
                    if (a == 0) {
                      return 0;
                    }
                    uint256 c = a * b;
                    assert(c / a == b);
                    return c;
                  }
                
                  function div(uint256 a, uint256 b) internal pure returns (uint256) {
                    uint256 c = a / b;
                    return c;
                  }
                
                  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
                    assert(b <= a);
                    return a - b;
                  }
                
                  function add(uint256 a, uint256 b) internal pure returns (uint256) {
                    uint256 c = a + b;
                    assert(c >= a);
                    return c;
                  }
                
                  function ceil(uint256 a, uint256 m) internal pure returns (uint256) {
                    uint256 c = add(a,m);
                    uint256 d = sub(c,1);
                    return mul(div(d,m),m);
                  }
                }
                
                contract ERC20Detailed is IERC20 {
                
                  string private _name;
                  string private _symbol;
                  uint8 private _decimals;
                
                  constructor(string memory name, string memory symbol, uint8 decimals) public {
                    _name = name;
                    _symbol = symbol;
                    _decimals = decimals;
                  }
                
                  function name() public view returns(string memory) {
                    return _name;
                  }
                
                  function symbol() public view returns(string memory) {
                    return _symbol;
                  }
                
                  function decimals() public view returns(uint8) {
                    return _decimals;
                  }
                }
                
                contract Statera is ERC20Detailed {
                
                  using SafeMath for uint256;
                  mapping (address => uint256) private _balances;
                  mapping (address => mapping (address => uint256)) private _allowed;
                
                  string constant tokenName = "Statera";
                  string constant tokenSymbol = "STA";
                  uint8  constant tokenDecimals = 18;
                  uint256 _totalSupply = 101000000000000000000000000;
                  uint256 public basePercent = 100;
                
                  constructor() public payable ERC20Detailed(tokenName, tokenSymbol, tokenDecimals) {
                    _issue(msg.sender, _totalSupply);
                  }
                
                  function totalSupply() public view returns (uint256) {
                    return _totalSupply;
                  }
                
                  function balanceOf(address owner) public view returns (uint256) {
                    return _balances[owner];
                  }
                
                  function allowance(address owner, address spender) public view returns (uint256) {
                    return _allowed[owner][spender];
                  }
                
                  function cut(uint256 value) public view returns (uint256)  {
                    uint256 roundValue = value.ceil(basePercent);
                    uint256 cutValue = roundValue.mul(basePercent).div(10000);
                    return cutValue;
                  }
                
                  function transfer(address to, uint256 value) public returns (bool) {
                    require(value <= _balances[msg.sender]);
                    require(to != address(0));
                
                    uint256 tokensToBurn = cut(value);
                    uint256 tokensToTransfer = value.sub(tokensToBurn);
                
                    _balances[msg.sender] = _balances[msg.sender].sub(value);
                    _balances[to] = _balances[to].add(tokensToTransfer);
                
                    _totalSupply = _totalSupply.sub(tokensToBurn);
                
                    emit Transfer(msg.sender, to, tokensToTransfer);
                    emit Transfer(msg.sender, address(0), tokensToBurn);
                    return true;
                  }
                
                
                  function approve(address spender, uint256 value) public returns (bool) {
                    require(spender != address(0));
                    _allowed[msg.sender][spender] = value;
                    emit Approval(msg.sender, spender, value);
                    return true;
                  }
                
                  function transferFrom(address from, address to, uint256 value) public returns (bool) {
                    require(value <= _balances[from]);
                    require(value <= _allowed[from][msg.sender]);
                    require(to != address(0));
                
                    _balances[from] = _balances[from].sub(value);
                
                    uint256 tokensToBurn = cut(value);
                    uint256 tokensToTransfer = value.sub(tokensToBurn);
                
                    _balances[to] = _balances[to].add(tokensToTransfer);
                    _totalSupply = _totalSupply.sub(tokensToBurn);
                
                    _allowed[from][msg.sender] = _allowed[from][msg.sender].sub(value);
                
                    emit Transfer(from, to, tokensToTransfer);
                    emit Transfer(from, address(0), tokensToBurn);
                
                    return true;
                  }
                
                  function upAllowance(address spender, uint256 addedValue) public returns (bool) {
                    require(spender != address(0));
                    _allowed[msg.sender][spender] = (_allowed[msg.sender][spender].add(addedValue));
                    emit Approval(msg.sender, spender, _allowed[msg.sender][spender]);
                    return true;
                  }
                
                  function downAllowance(address spender, uint256 subtractedValue) public returns (bool) {
                    require(spender != address(0));
                    _allowed[msg.sender][spender] = (_allowed[msg.sender][spender].sub(subtractedValue));
                    emit Approval(msg.sender, spender, _allowed[msg.sender][spender]);
                    return true;
                  }
                
                  function _issue(address account, uint256 amount) internal {
                    require(amount != 0);
                    _balances[account] = _balances[account].add(amount);
                    emit Transfer(address(0), account, amount);
                  }
                
                  function destroy(uint256 amount) external {
                    _destroy(msg.sender, amount);
                  }
                
                  function _destroy(address account, uint256 amount) internal {
                    require(amount != 0);
                    require(amount <= _balances[account]);
                    _totalSupply = _totalSupply.sub(amount);
                    _balances[account] = _balances[account].sub(amount);
                    emit Transfer(account, address(0), amount);
                  }
                
                  function destroyFrom(address account, uint256 amount) external {
                    require(amount <= _allowed[account][msg.sender]);
                    _allowed[account][msg.sender] = _allowed[account][msg.sender].sub(amount);
                    _destroy(account, amount);
                  }
                }

                File 3 of 4: Vyper_contract
                # @title Uniswap Exchange Interface V1
                # @notice Source code found at https://github.com/uniswap
                # @notice Use at your own risk
                
                contract Factory():
                    def getExchange(token_addr: address) -> address: constant
                
                contract Exchange():
                    def getEthToTokenOutputPrice(tokens_bought: uint256) -> uint256(wei): constant
                    def ethToTokenTransferInput(min_tokens: uint256, deadline: timestamp, recipient: address) -> uint256: modifying
                    def ethToTokenTransferOutput(tokens_bought: uint256, deadline: timestamp, recipient: address) -> uint256(wei): modifying
                
                TokenPurchase: event({buyer: indexed(address), eth_sold: indexed(uint256(wei)), tokens_bought: indexed(uint256)})
                EthPurchase: event({buyer: indexed(address), tokens_sold: indexed(uint256), eth_bought: indexed(uint256(wei))})
                AddLiquidity: event({provider: indexed(address), eth_amount: indexed(uint256(wei)), token_amount: indexed(uint256)})
                RemoveLiquidity: event({provider: indexed(address), eth_amount: indexed(uint256(wei)), token_amount: indexed(uint256)})
                Transfer: event({_from: indexed(address), _to: indexed(address), _value: uint256})
                Approval: event({_owner: indexed(address), _spender: indexed(address), _value: uint256})
                
                name: public(bytes32)                             # Uniswap V1
                symbol: public(bytes32)                           # UNI-V1
                decimals: public(uint256)                         # 18
                totalSupply: public(uint256)                      # total number of UNI in existence
                balances: uint256[address]                        # UNI balance of an address
                allowances: (uint256[address])[address]           # UNI allowance of one address on another
                token: address(ERC20)                             # address of the ERC20 token traded on this contract
                factory: Factory                                  # interface for the factory that created this contract
                
                # @dev This function acts as a contract constructor which is not currently supported in contracts deployed
                #      using create_with_code_of(). It is called once by the factory during contract creation.
                @public
                def setup(token_addr: address):
                    assert (self.factory == ZERO_ADDRESS and self.token == ZERO_ADDRESS) and token_addr != ZERO_ADDRESS
                    self.factory = msg.sender
                    self.token = token_addr
                    self.name = 0x556e697377617020563100000000000000000000000000000000000000000000
                    self.symbol = 0x554e492d56310000000000000000000000000000000000000000000000000000
                    self.decimals = 18
                
                # @notice Deposit ETH and Tokens (self.token) at current ratio to mint UNI tokens.
                # @dev min_liquidity does nothing when total UNI supply is 0.
                # @param min_liquidity Minimum number of UNI sender will mint if total UNI supply is greater than 0.
                # @param max_tokens Maximum number of tokens deposited. Deposits max amount if total UNI supply is 0.
                # @param deadline Time after which this transaction can no longer be executed.
                # @return The amount of UNI minted.
                @public
                @payable
                def addLiquidity(min_liquidity: uint256, max_tokens: uint256, deadline: timestamp) -> uint256:
                    assert deadline > block.timestamp and (max_tokens > 0 and msg.value > 0)
                    total_liquidity: uint256 = self.totalSupply
                    if total_liquidity > 0:
                        assert min_liquidity > 0
                        eth_reserve: uint256(wei) = self.balance - msg.value
                        token_reserve: uint256 = self.token.balanceOf(self)
                        token_amount: uint256 = msg.value * token_reserve / eth_reserve + 1
                        liquidity_minted: uint256 = msg.value * total_liquidity / eth_reserve
                        assert max_tokens >= token_amount and liquidity_minted >= min_liquidity
                        self.balances[msg.sender] += liquidity_minted
                        self.totalSupply = total_liquidity + liquidity_minted
                        assert self.token.transferFrom(msg.sender, self, token_amount)
                        log.AddLiquidity(msg.sender, msg.value, token_amount)
                        log.Transfer(ZERO_ADDRESS, msg.sender, liquidity_minted)
                        return liquidity_minted
                    else:
                        assert (self.factory != ZERO_ADDRESS and self.token != ZERO_ADDRESS) and msg.value >= 1000000000
                        assert self.factory.getExchange(self.token) == self
                        token_amount: uint256 = max_tokens
                        initial_liquidity: uint256 = as_unitless_number(self.balance)
                        self.totalSupply = initial_liquidity
                        self.balances[msg.sender] = initial_liquidity
                        assert self.token.transferFrom(msg.sender, self, token_amount)
                        log.AddLiquidity(msg.sender, msg.value, token_amount)
                        log.Transfer(ZERO_ADDRESS, msg.sender, initial_liquidity)
                        return initial_liquidity
                
                # @dev Burn UNI tokens to withdraw ETH and Tokens at current ratio.
                # @param amount Amount of UNI burned.
                # @param min_eth Minimum ETH withdrawn.
                # @param min_tokens Minimum Tokens withdrawn.
                # @param deadline Time after which this transaction can no longer be executed.
                # @return The amount of ETH and Tokens withdrawn.
                @public
                def removeLiquidity(amount: uint256, min_eth: uint256(wei), min_tokens: uint256, deadline: timestamp) -> (uint256(wei), uint256):
                    assert (amount > 0 and deadline > block.timestamp) and (min_eth > 0 and min_tokens > 0)
                    total_liquidity: uint256 = self.totalSupply
                    assert total_liquidity > 0
                    token_reserve: uint256 = self.token.balanceOf(self)
                    eth_amount: uint256(wei) = amount * self.balance / total_liquidity
                    token_amount: uint256 = amount * token_reserve / total_liquidity
                    assert eth_amount >= min_eth and token_amount >= min_tokens
                    self.balances[msg.sender] -= amount
                    self.totalSupply = total_liquidity - amount
                    send(msg.sender, eth_amount)
                    assert self.token.transfer(msg.sender, token_amount)
                    log.RemoveLiquidity(msg.sender, eth_amount, token_amount)
                    log.Transfer(msg.sender, ZERO_ADDRESS, amount)
                    return eth_amount, token_amount
                
                # @dev Pricing function for converting between ETH and Tokens.
                # @param input_amount Amount of ETH or Tokens being sold.
                # @param input_reserve Amount of ETH or Tokens (input type) in exchange reserves.
                # @param output_reserve Amount of ETH or Tokens (output type) in exchange reserves.
                # @return Amount of ETH or Tokens bought.
                @private
                @constant
                def getInputPrice(input_amount: uint256, input_reserve: uint256, output_reserve: uint256) -> uint256:
                    assert input_reserve > 0 and output_reserve > 0
                    input_amount_with_fee: uint256 = input_amount * 997
                    numerator: uint256 = input_amount_with_fee * output_reserve
                    denominator: uint256 = (input_reserve * 1000) + input_amount_with_fee
                    return numerator / denominator
                
                # @dev Pricing function for converting between ETH and Tokens.
                # @param output_amount Amount of ETH or Tokens being bought.
                # @param input_reserve Amount of ETH or Tokens (input type) in exchange reserves.
                # @param output_reserve Amount of ETH or Tokens (output type) in exchange reserves.
                # @return Amount of ETH or Tokens sold.
                @private
                @constant
                def getOutputPrice(output_amount: uint256, input_reserve: uint256, output_reserve: uint256) -> uint256:
                    assert input_reserve > 0 and output_reserve > 0
                    numerator: uint256 = input_reserve * output_amount * 1000
                    denominator: uint256 = (output_reserve - output_amount) * 997
                    return numerator / denominator + 1
                
                @private
                def ethToTokenInput(eth_sold: uint256(wei), min_tokens: uint256, deadline: timestamp, buyer: address, recipient: address) -> uint256:
                    assert deadline >= block.timestamp and (eth_sold > 0 and min_tokens > 0)
                    token_reserve: uint256 = self.token.balanceOf(self)
                    tokens_bought: uint256 = self.getInputPrice(as_unitless_number(eth_sold), as_unitless_number(self.balance - eth_sold), token_reserve)
                    assert tokens_bought >= min_tokens
                    assert self.token.transfer(recipient, tokens_bought)
                    log.TokenPurchase(buyer, eth_sold, tokens_bought)
                    return tokens_bought
                
                # @notice Convert ETH to Tokens.
                # @dev User specifies exact input (msg.value).
                # @dev User cannot specify minimum output or deadline.
                @public
                @payable
                def __default__():
                    self.ethToTokenInput(msg.value, 1, block.timestamp, msg.sender, msg.sender)
                
                # @notice Convert ETH to Tokens.
                # @dev User specifies exact input (msg.value) and minimum output.
                # @param min_tokens Minimum Tokens bought.
                # @param deadline Time after which this transaction can no longer be executed.
                # @return Amount of Tokens bought.
                @public
                @payable
                def ethToTokenSwapInput(min_tokens: uint256, deadline: timestamp) -> uint256:
                    return self.ethToTokenInput(msg.value, min_tokens, deadline, msg.sender, msg.sender)
                
                # @notice Convert ETH to Tokens and transfers Tokens to recipient.
                # @dev User specifies exact input (msg.value) and minimum output
                # @param min_tokens Minimum Tokens bought.
                # @param deadline Time after which this transaction can no longer be executed.
                # @param recipient The address that receives output Tokens.
                # @return Amount of Tokens bought.
                @public
                @payable
                def ethToTokenTransferInput(min_tokens: uint256, deadline: timestamp, recipient: address) -> uint256:
                    assert recipient != self and recipient != ZERO_ADDRESS
                    return self.ethToTokenInput(msg.value, min_tokens, deadline, msg.sender, recipient)
                
                @private
                def ethToTokenOutput(tokens_bought: uint256, max_eth: uint256(wei), deadline: timestamp, buyer: address, recipient: address) -> uint256(wei):
                    assert deadline >= block.timestamp and (tokens_bought > 0 and max_eth > 0)
                    token_reserve: uint256 = self.token.balanceOf(self)
                    eth_sold: uint256 = self.getOutputPrice(tokens_bought, as_unitless_number(self.balance - max_eth), token_reserve)
                    # Throws if eth_sold > max_eth
                    eth_refund: uint256(wei) = max_eth - as_wei_value(eth_sold, 'wei')
                    if eth_refund > 0:
                        send(buyer, eth_refund)
                    assert self.token.transfer(recipient, tokens_bought)
                    log.TokenPurchase(buyer, as_wei_value(eth_sold, 'wei'), tokens_bought)
                    return as_wei_value(eth_sold, 'wei')
                
                # @notice Convert ETH to Tokens.
                # @dev User specifies maximum input (msg.value) and exact output.
                # @param tokens_bought Amount of tokens bought.
                # @param deadline Time after which this transaction can no longer be executed.
                # @return Amount of ETH sold.
                @public
                @payable
                def ethToTokenSwapOutput(tokens_bought: uint256, deadline: timestamp) -> uint256(wei):
                    return self.ethToTokenOutput(tokens_bought, msg.value, deadline, msg.sender, msg.sender)
                
                # @notice Convert ETH to Tokens and transfers Tokens to recipient.
                # @dev User specifies maximum input (msg.value) and exact output.
                # @param tokens_bought Amount of tokens bought.
                # @param deadline Time after which this transaction can no longer be executed.
                # @param recipient The address that receives output Tokens.
                # @return Amount of ETH sold.
                @public
                @payable
                def ethToTokenTransferOutput(tokens_bought: uint256, deadline: timestamp, recipient: address) -> uint256(wei):
                    assert recipient != self and recipient != ZERO_ADDRESS
                    return self.ethToTokenOutput(tokens_bought, msg.value, deadline, msg.sender, recipient)
                
                @private
                def tokenToEthInput(tokens_sold: uint256, min_eth: uint256(wei), deadline: timestamp, buyer: address, recipient: address) -> uint256(wei):
                    assert deadline >= block.timestamp and (tokens_sold > 0 and min_eth > 0)
                    token_reserve: uint256 = self.token.balanceOf(self)
                    eth_bought: uint256 = self.getInputPrice(tokens_sold, token_reserve, as_unitless_number(self.balance))
                    wei_bought: uint256(wei) = as_wei_value(eth_bought, 'wei')
                    assert wei_bought >= min_eth
                    send(recipient, wei_bought)
                    assert self.token.transferFrom(buyer, self, tokens_sold)
                    log.EthPurchase(buyer, tokens_sold, wei_bought)
                    return wei_bought
                
                
                # @notice Convert Tokens to ETH.
                # @dev User specifies exact input and minimum output.
                # @param tokens_sold Amount of Tokens sold.
                # @param min_eth Minimum ETH purchased.
                # @param deadline Time after which this transaction can no longer be executed.
                # @return Amount of ETH bought.
                @public
                def tokenToEthSwapInput(tokens_sold: uint256, min_eth: uint256(wei), deadline: timestamp) -> uint256(wei):
                    return self.tokenToEthInput(tokens_sold, min_eth, deadline, msg.sender, msg.sender)
                
                # @notice Convert Tokens to ETH and transfers ETH to recipient.
                # @dev User specifies exact input and minimum output.
                # @param tokens_sold Amount of Tokens sold.
                # @param min_eth Minimum ETH purchased.
                # @param deadline Time after which this transaction can no longer be executed.
                # @param recipient The address that receives output ETH.
                # @return Amount of ETH bought.
                @public
                def tokenToEthTransferInput(tokens_sold: uint256, min_eth: uint256(wei), deadline: timestamp, recipient: address) -> uint256(wei):
                    assert recipient != self and recipient != ZERO_ADDRESS
                    return self.tokenToEthInput(tokens_sold, min_eth, deadline, msg.sender, recipient)
                
                @private
                def tokenToEthOutput(eth_bought: uint256(wei), max_tokens: uint256, deadline: timestamp, buyer: address, recipient: address) -> uint256:
                    assert deadline >= block.timestamp and eth_bought > 0
                    token_reserve: uint256 = self.token.balanceOf(self)
                    tokens_sold: uint256 = self.getOutputPrice(as_unitless_number(eth_bought), token_reserve, as_unitless_number(self.balance))
                    # tokens sold is always > 0
                    assert max_tokens >= tokens_sold
                    send(recipient, eth_bought)
                    assert self.token.transferFrom(buyer, self, tokens_sold)
                    log.EthPurchase(buyer, tokens_sold, eth_bought)
                    return tokens_sold
                
                # @notice Convert Tokens to ETH.
                # @dev User specifies maximum input and exact output.
                # @param eth_bought Amount of ETH purchased.
                # @param max_tokens Maximum Tokens sold.
                # @param deadline Time after which this transaction can no longer be executed.
                # @return Amount of Tokens sold.
                @public
                def tokenToEthSwapOutput(eth_bought: uint256(wei), max_tokens: uint256, deadline: timestamp) -> uint256:
                    return self.tokenToEthOutput(eth_bought, max_tokens, deadline, msg.sender, msg.sender)
                
                # @notice Convert Tokens to ETH and transfers ETH to recipient.
                # @dev User specifies maximum input and exact output.
                # @param eth_bought Amount of ETH purchased.
                # @param max_tokens Maximum Tokens sold.
                # @param deadline Time after which this transaction can no longer be executed.
                # @param recipient The address that receives output ETH.
                # @return Amount of Tokens sold.
                @public
                def tokenToEthTransferOutput(eth_bought: uint256(wei), max_tokens: uint256, deadline: timestamp, recipient: address) -> uint256:
                    assert recipient != self and recipient != ZERO_ADDRESS
                    return self.tokenToEthOutput(eth_bought, max_tokens, deadline, msg.sender, recipient)
                
                @private
                def tokenToTokenInput(tokens_sold: uint256, min_tokens_bought: uint256, min_eth_bought: uint256(wei), deadline: timestamp, buyer: address, recipient: address, exchange_addr: address) -> uint256:
                    assert (deadline >= block.timestamp and tokens_sold > 0) and (min_tokens_bought > 0 and min_eth_bought > 0)
                    assert exchange_addr != self and exchange_addr != ZERO_ADDRESS
                    token_reserve: uint256 = self.token.balanceOf(self)
                    eth_bought: uint256 = self.getInputPrice(tokens_sold, token_reserve, as_unitless_number(self.balance))
                    wei_bought: uint256(wei) = as_wei_value(eth_bought, 'wei')
                    assert wei_bought >= min_eth_bought
                    assert self.token.transferFrom(buyer, self, tokens_sold)
                    tokens_bought: uint256 = Exchange(exchange_addr).ethToTokenTransferInput(min_tokens_bought, deadline, recipient, value=wei_bought)
                    log.EthPurchase(buyer, tokens_sold, wei_bought)
                    return tokens_bought
                
                # @notice Convert Tokens (self.token) to Tokens (token_addr).
                # @dev User specifies exact input and minimum output.
                # @param tokens_sold Amount of Tokens sold.
                # @param min_tokens_bought Minimum Tokens (token_addr) purchased.
                # @param min_eth_bought Minimum ETH purchased as intermediary.
                # @param deadline Time after which this transaction can no longer be executed.
                # @param token_addr The address of the token being purchased.
                # @return Amount of Tokens (token_addr) bought.
                @public
                def tokenToTokenSwapInput(tokens_sold: uint256, min_tokens_bought: uint256, min_eth_bought: uint256(wei), deadline: timestamp, token_addr: address) -> uint256:
                    exchange_addr: address = self.factory.getExchange(token_addr)
                    return self.tokenToTokenInput(tokens_sold, min_tokens_bought, min_eth_bought, deadline, msg.sender, msg.sender, exchange_addr)
                
                # @notice Convert Tokens (self.token) to Tokens (token_addr) and transfers
                #         Tokens (token_addr) to recipient.
                # @dev User specifies exact input and minimum output.
                # @param tokens_sold Amount of Tokens sold.
                # @param min_tokens_bought Minimum Tokens (token_addr) purchased.
                # @param min_eth_bought Minimum ETH purchased as intermediary.
                # @param deadline Time after which this transaction can no longer be executed.
                # @param recipient The address that receives output ETH.
                # @param token_addr The address of the token being purchased.
                # @return Amount of Tokens (token_addr) bought.
                @public
                def tokenToTokenTransferInput(tokens_sold: uint256, min_tokens_bought: uint256, min_eth_bought: uint256(wei), deadline: timestamp, recipient: address, token_addr: address) -> uint256:
                    exchange_addr: address = self.factory.getExchange(token_addr)
                    return self.tokenToTokenInput(tokens_sold, min_tokens_bought, min_eth_bought, deadline, msg.sender, recipient, exchange_addr)
                
                @private
                def tokenToTokenOutput(tokens_bought: uint256, max_tokens_sold: uint256, max_eth_sold: uint256(wei), deadline: timestamp, buyer: address, recipient: address, exchange_addr: address) -> uint256:
                    assert deadline >= block.timestamp and (tokens_bought > 0 and max_eth_sold > 0)
                    assert exchange_addr != self and exchange_addr != ZERO_ADDRESS
                    eth_bought: uint256(wei) = Exchange(exchange_addr).getEthToTokenOutputPrice(tokens_bought)
                    token_reserve: uint256 = self.token.balanceOf(self)
                    tokens_sold: uint256 = self.getOutputPrice(as_unitless_number(eth_bought), token_reserve, as_unitless_number(self.balance))
                    # tokens sold is always > 0
                    assert max_tokens_sold >= tokens_sold and max_eth_sold >= eth_bought
                    assert self.token.transferFrom(buyer, self, tokens_sold)
                    eth_sold: uint256(wei) = Exchange(exchange_addr).ethToTokenTransferOutput(tokens_bought, deadline, recipient, value=eth_bought)
                    log.EthPurchase(buyer, tokens_sold, eth_bought)
                    return tokens_sold
                
                # @notice Convert Tokens (self.token) to Tokens (token_addr).
                # @dev User specifies maximum input and exact output.
                # @param tokens_bought Amount of Tokens (token_addr) bought.
                # @param max_tokens_sold Maximum Tokens (self.token) sold.
                # @param max_eth_sold Maximum ETH purchased as intermediary.
                # @param deadline Time after which this transaction can no longer be executed.
                # @param token_addr The address of the token being purchased.
                # @return Amount of Tokens (self.token) sold.
                @public
                def tokenToTokenSwapOutput(tokens_bought: uint256, max_tokens_sold: uint256, max_eth_sold: uint256(wei), deadline: timestamp, token_addr: address) -> uint256:
                    exchange_addr: address = self.factory.getExchange(token_addr)
                    return self.tokenToTokenOutput(tokens_bought, max_tokens_sold, max_eth_sold, deadline, msg.sender, msg.sender, exchange_addr)
                
                # @notice Convert Tokens (self.token) to Tokens (token_addr) and transfers
                #         Tokens (token_addr) to recipient.
                # @dev User specifies maximum input and exact output.
                # @param tokens_bought Amount of Tokens (token_addr) bought.
                # @param max_tokens_sold Maximum Tokens (self.token) sold.
                # @param max_eth_sold Maximum ETH purchased as intermediary.
                # @param deadline Time after which this transaction can no longer be executed.
                # @param recipient The address that receives output ETH.
                # @param token_addr The address of the token being purchased.
                # @return Amount of Tokens (self.token) sold.
                @public
                def tokenToTokenTransferOutput(tokens_bought: uint256, max_tokens_sold: uint256, max_eth_sold: uint256(wei), deadline: timestamp, recipient: address, token_addr: address) -> uint256:
                    exchange_addr: address = self.factory.getExchange(token_addr)
                    return self.tokenToTokenOutput(tokens_bought, max_tokens_sold, max_eth_sold, deadline, msg.sender, recipient, exchange_addr)
                
                # @notice Convert Tokens (self.token) to Tokens (exchange_addr.token).
                # @dev Allows trades through contracts that were not deployed from the same factory.
                # @dev User specifies exact input and minimum output.
                # @param tokens_sold Amount of Tokens sold.
                # @param min_tokens_bought Minimum Tokens (token_addr) purchased.
                # @param min_eth_bought Minimum ETH purchased as intermediary.
                # @param deadline Time after which this transaction can no longer be executed.
                # @param exchange_addr The address of the exchange for the token being purchased.
                # @return Amount of Tokens (exchange_addr.token) bought.
                @public
                def tokenToExchangeSwapInput(tokens_sold: uint256, min_tokens_bought: uint256, min_eth_bought: uint256(wei), deadline: timestamp, exchange_addr: address) -> uint256:
                    return self.tokenToTokenInput(tokens_sold, min_tokens_bought, min_eth_bought, deadline, msg.sender, msg.sender, exchange_addr)
                
                # @notice Convert Tokens (self.token) to Tokens (exchange_addr.token) and transfers
                #         Tokens (exchange_addr.token) to recipient.
                # @dev Allows trades through contracts that were not deployed from the same factory.
                # @dev User specifies exact input and minimum output.
                # @param tokens_sold Amount of Tokens sold.
                # @param min_tokens_bought Minimum Tokens (token_addr) purchased.
                # @param min_eth_bought Minimum ETH purchased as intermediary.
                # @param deadline Time after which this transaction can no longer be executed.
                # @param recipient The address that receives output ETH.
                # @param exchange_addr The address of the exchange for the token being purchased.
                # @return Amount of Tokens (exchange_addr.token) bought.
                @public
                def tokenToExchangeTransferInput(tokens_sold: uint256, min_tokens_bought: uint256, min_eth_bought: uint256(wei), deadline: timestamp, recipient: address, exchange_addr: address) -> uint256:
                    assert recipient != self
                    return self.tokenToTokenInput(tokens_sold, min_tokens_bought, min_eth_bought, deadline, msg.sender, recipient, exchange_addr)
                
                # @notice Convert Tokens (self.token) to Tokens (exchange_addr.token).
                # @dev Allows trades through contracts that were not deployed from the same factory.
                # @dev User specifies maximum input and exact output.
                # @param tokens_bought Amount of Tokens (token_addr) bought.
                # @param max_tokens_sold Maximum Tokens (self.token) sold.
                # @param max_eth_sold Maximum ETH purchased as intermediary.
                # @param deadline Time after which this transaction can no longer be executed.
                # @param exchange_addr The address of the exchange for the token being purchased.
                # @return Amount of Tokens (self.token) sold.
                @public
                def tokenToExchangeSwapOutput(tokens_bought: uint256, max_tokens_sold: uint256, max_eth_sold: uint256(wei), deadline: timestamp, exchange_addr: address) -> uint256:
                    return self.tokenToTokenOutput(tokens_bought, max_tokens_sold, max_eth_sold, deadline, msg.sender, msg.sender, exchange_addr)
                
                # @notice Convert Tokens (self.token) to Tokens (exchange_addr.token) and transfers
                #         Tokens (exchange_addr.token) to recipient.
                # @dev Allows trades through contracts that were not deployed from the same factory.
                # @dev User specifies maximum input and exact output.
                # @param tokens_bought Amount of Tokens (token_addr) bought.
                # @param max_tokens_sold Maximum Tokens (self.token) sold.
                # @param max_eth_sold Maximum ETH purchased as intermediary.
                # @param deadline Time after which this transaction can no longer be executed.
                # @param recipient The address that receives output ETH.
                # @param token_addr The address of the token being purchased.
                # @return Amount of Tokens (self.token) sold.
                @public
                def tokenToExchangeTransferOutput(tokens_bought: uint256, max_tokens_sold: uint256, max_eth_sold: uint256(wei), deadline: timestamp, recipient: address, exchange_addr: address) -> uint256:
                    assert recipient != self
                    return self.tokenToTokenOutput(tokens_bought, max_tokens_sold, max_eth_sold, deadline, msg.sender, recipient, exchange_addr)
                
                # @notice Public price function for ETH to Token trades with an exact input.
                # @param eth_sold Amount of ETH sold.
                # @return Amount of Tokens that can be bought with input ETH.
                @public
                @constant
                def getEthToTokenInputPrice(eth_sold: uint256(wei)) -> uint256:
                    assert eth_sold > 0
                    token_reserve: uint256 = self.token.balanceOf(self)
                    return self.getInputPrice(as_unitless_number(eth_sold), as_unitless_number(self.balance), token_reserve)
                
                # @notice Public price function for ETH to Token trades with an exact output.
                # @param tokens_bought Amount of Tokens bought.
                # @return Amount of ETH needed to buy output Tokens.
                @public
                @constant
                def getEthToTokenOutputPrice(tokens_bought: uint256) -> uint256(wei):
                    assert tokens_bought > 0
                    token_reserve: uint256 = self.token.balanceOf(self)
                    eth_sold: uint256 = self.getOutputPrice(tokens_bought, as_unitless_number(self.balance), token_reserve)
                    return as_wei_value(eth_sold, 'wei')
                
                # @notice Public price function for Token to ETH trades with an exact input.
                # @param tokens_sold Amount of Tokens sold.
                # @return Amount of ETH that can be bought with input Tokens.
                @public
                @constant
                def getTokenToEthInputPrice(tokens_sold: uint256) -> uint256(wei):
                    assert tokens_sold > 0
                    token_reserve: uint256 = self.token.balanceOf(self)
                    eth_bought: uint256 = self.getInputPrice(tokens_sold, token_reserve, as_unitless_number(self.balance))
                    return as_wei_value(eth_bought, 'wei')
                
                # @notice Public price function for Token to ETH trades with an exact output.
                # @param eth_bought Amount of output ETH.
                # @return Amount of Tokens needed to buy output ETH.
                @public
                @constant
                def getTokenToEthOutputPrice(eth_bought: uint256(wei)) -> uint256:
                    assert eth_bought > 0
                    token_reserve: uint256 = self.token.balanceOf(self)
                    return self.getOutputPrice(as_unitless_number(eth_bought), token_reserve, as_unitless_number(self.balance))
                
                # @return Address of Token that is sold on this exchange.
                @public
                @constant
                def tokenAddress() -> address:
                    return self.token
                
                # @return Address of factory that created this exchange.
                @public
                @constant
                def factoryAddress() -> address(Factory):
                    return self.factory
                
                # ERC20 compatibility for exchange liquidity modified from
                # https://github.com/ethereum/vyper/blob/master/examples/tokens/ERC20.vy
                @public
                @constant
                def balanceOf(_owner : address) -> uint256:
                    return self.balances[_owner]
                
                @public
                def transfer(_to : address, _value : uint256) -> bool:
                    self.balances[msg.sender] -= _value
                    self.balances[_to] += _value
                    log.Transfer(msg.sender, _to, _value)
                    return True
                
                @public
                def transferFrom(_from : address, _to : address, _value : uint256) -> bool:
                    self.balances[_from] -= _value
                    self.balances[_to] += _value
                    self.allowances[_from][msg.sender] -= _value
                    log.Transfer(_from, _to, _value)
                    return True
                
                @public
                def approve(_spender : address, _value : uint256) -> bool:
                    self.allowances[msg.sender][_spender] = _value
                    log.Approval(msg.sender, _spender, _value)
                    return True
                
                @public
                @constant
                def allowance(_owner : address, _spender : address) -> uint256:
                    return self.allowances[_owner][_spender]

                File 4 of 4: GasToken2
                pragma solidity ^0.4.10;
                
                contract GasToken2 {
                    //////////////////////////////////////////////////////////////////////////
                    // RLP.sol
                    // Due to some unexplained bug, we get a slightly different bytecode if 
                    // we use an import, and are then unable to verify the code in Etherscan
                    //////////////////////////////////////////////////////////////////////////
                    
                    uint256 constant ADDRESS_BYTES = 20;
                    uint256 constant MAX_SINGLE_BYTE = 128;
                    uint256 constant MAX_NONCE = 256**9 - 1;
                
                    // count number of bytes required to represent an unsigned integer
                    function count_bytes(uint256 n) constant internal returns (uint256 c) {
                        uint i = 0;
                        uint mask = 1;
                        while (n >= mask) {
                            i += 1;
                            mask *= 256;
                        }
                
                        return i;
                    }
                
                    function mk_contract_address(address a, uint256 n) constant internal returns (address rlp) {
                        /*
                         * make sure the RLP encoding fits in one word:
                         * total_length      1 byte
                         * address_length    1 byte
                         * address          20 bytes
                         * nonce_length      1 byte (or 0)
                         * nonce           1-9 bytes
                         *                ==========
                         *                24-32 bytes
                         */
                        require(n <= MAX_NONCE);
                
                        // number of bytes required to write down the nonce
                        uint256 nonce_bytes;
                        // length in bytes of the RLP encoding of the nonce
                        uint256 nonce_rlp_len;
                
                        if (0 < n && n < MAX_SINGLE_BYTE) {
                            // nonce fits in a single byte
                            // RLP(nonce) = nonce
                            nonce_bytes = 1;
                            nonce_rlp_len = 1;
                        } else {
                            // RLP(nonce) = [num_bytes_in_nonce nonce]
                            nonce_bytes = count_bytes(n);
                            nonce_rlp_len = nonce_bytes + 1;
                        }
                
                        // [address_length(1) address(20) nonce_length(0 or 1) nonce(1-9)]
                        uint256 tot_bytes = 1 + ADDRESS_BYTES + nonce_rlp_len;
                
                        // concatenate all parts of the RLP encoding in the leading bytes of
                        // one 32-byte word
                        uint256 word = ((192 + tot_bytes) * 256**31) +
                                       ((128 + ADDRESS_BYTES) * 256**30) +
                                       (uint256(a) * 256**10);
                
                        if (0 < n && n < MAX_SINGLE_BYTE) {
                            word += n * 256**9;
                        } else {
                            word += (128 + nonce_bytes) * 256**9;
                            word += n * 256**(9 - nonce_bytes);
                        }
                
                        uint256 hash;
                
                        assembly {
                            let mem_start := mload(0x40)        // get a pointer to free memory
                            mstore(0x40, add(mem_start, 0x20))  // update the pointer
                
                            mstore(mem_start, word)             // store the rlp encoding
                            hash := sha3(mem_start,
                                         add(tot_bytes, 1))     // hash the rlp encoding
                        }
                
                        // interpret hash as address (20 least significant bytes)
                        return address(hash);
                    }
                    
                    //////////////////////////////////////////////////////////////////////////
                    // Generic ERC20
                    //////////////////////////////////////////////////////////////////////////
                
                    // owner -> amount
                    mapping(address => uint256) s_balances;
                    // owner -> spender -> max amount
                    mapping(address => mapping(address => uint256)) s_allowances;
                
                    event Transfer(address indexed from, address indexed to, uint256 value);
                
                    event Approval(address indexed owner, address indexed spender, uint256 value);
                
                    // Spec: Get the account balance of another account with address `owner`
                    function balanceOf(address owner) public constant returns (uint256 balance) {
                        return s_balances[owner];
                    }
                
                    function internalTransfer(address from, address to, uint256 value) internal returns (bool success) {
                        if (value <= s_balances[from]) {
                            s_balances[from] -= value;
                            s_balances[to] += value;
                            Transfer(from, to, value);
                            return true;
                        } else {
                            return false;
                        }
                    }
                
                    // Spec: Send `value` amount of tokens to address `to`
                    function transfer(address to, uint256 value) public returns (bool success) {
                        address from = msg.sender;
                        return internalTransfer(from, to, value);
                    }
                
                    // Spec: Send `value` amount of tokens from address `from` to address `to`
                    function transferFrom(address from, address to, uint256 value) public returns (bool success) {
                        address spender = msg.sender;
                        if(value <= s_allowances[from][spender] && internalTransfer(from, to, value)) {
                            s_allowances[from][spender] -= value;
                            return true;
                        } else {
                            return false;
                        }
                    }
                
                    // Spec: Allow `spender` to withdraw from your account, multiple times, up
                    // to the `value` amount. If this function is called again it overwrites the
                    // current allowance with `value`.
                    function approve(address spender, uint256 value) public returns (bool success) {
                        address owner = msg.sender;
                        if (value != 0 && s_allowances[owner][spender] != 0) {
                            return false;
                        }
                        s_allowances[owner][spender] = value;
                        Approval(owner, spender, value);
                        return true;
                    }
                
                    // Spec: Returns the `amount` which `spender` is still allowed to withdraw
                    // from `owner`.
                    // What if the allowance is higher than the balance of the `owner`?
                    // Callers should be careful to use min(allowance, balanceOf) to make sure
                    // that the allowance is actually present in the account!
                    function allowance(address owner, address spender) public constant returns (uint256 remaining) {
                        return s_allowances[owner][spender];
                    }
                
                    //////////////////////////////////////////////////////////////////////////
                    // GasToken specifics
                    //////////////////////////////////////////////////////////////////////////
                
                    uint8 constant public decimals = 2;
                    string constant public name = "Gastoken.io";
                    string constant public symbol = "GST2";
                
                    // We build a queue of nonces at which child contracts are stored. s_head is
                    // the nonce at the head of the queue, s_tail is the nonce behind the tail
                    // of the queue. The queue grows at the head and shrinks from the tail.
                    // Note that when and only when a contract CREATEs another contract, the
                    // creating contract's nonce is incremented.
                    // The first child contract is created with nonce == 1, the second child
                    // contract is created with nonce == 2, and so on...
                    // For example, if there are child contracts at nonces [2,3,4],
                    // then s_head == 4 and s_tail == 1. If there are no child contracts,
                    // s_head == s_tail.
                    uint256 s_head;
                    uint256 s_tail;
                
                    // totalSupply gives  the number of tokens currently in existence
                    // Each token corresponds to one child contract that can be SELFDESTRUCTed
                    // for a gas refund.
                    function totalSupply() public constant returns (uint256 supply) {
                        return s_head - s_tail;
                    }
                
                    // Creates a child contract that can only be destroyed by this contract.
                    function makeChild() internal returns (address addr) {
                        assembly {
                            // EVM assembler of runtime portion of child contract:
                            //     ;; Pseudocode: if (msg.sender != 0x0000000000b3f879cb30fe243b4dfee438691c04) { throw; }
                            //     ;;             suicide(msg.sender)
                            //     PUSH15 0xb3f879cb30fe243b4dfee438691c04 ;; hardcoded address of this contract
                            //     CALLER
                            //     XOR
                            //     PC
                            //     JUMPI
                            //     CALLER
                            //     SELFDESTRUCT
                            // Or in binary: 6eb3f879cb30fe243b4dfee438691c043318585733ff
                            // Since the binary is so short (22 bytes), we can get away
                            // with a very simple initcode:
                            //     PUSH22 0x6eb3f879cb30fe243b4dfee438691c043318585733ff
                            //     PUSH1 0
                            //     MSTORE ;; at this point, memory locations mem[10] through
                            //            ;; mem[31] contain the runtime portion of the child
                            //            ;; contract. all that's left to do is to RETURN this
                            //            ;; chunk of memory.
                            //     PUSH1 22 ;; length
                            //     PUSH1 10 ;; offset
                            //     RETURN
                            // Or in binary: 756eb3f879cb30fe243b4dfee438691c043318585733ff6000526016600af3
                            // Almost done! All we have to do is put this short (31 bytes) blob into
                            // memory and call CREATE with the appropriate offsets.
                            let solidity_free_mem_ptr := mload(0x40)
                            mstore(solidity_free_mem_ptr, 0x00756eb3f879cb30fe243b4dfee438691c043318585733ff6000526016600af3)
                            addr := create(0, add(solidity_free_mem_ptr, 1), 31)
                        }
                    }
                
                    // Mints `value` new sub-tokens (e.g. cents, pennies, ...) by creating `value`
                    // new child contracts. The minted tokens are owned by the caller of this
                    // function.
                    function mint(uint256 value) public {
                        for (uint256 i = 0; i < value; i++) {
                            makeChild();
                        }
                        s_head += value;
                        s_balances[msg.sender] += value;
                    }
                
                    // Destroys `value` child contracts and updates s_tail.
                    //
                    // This function is affected by an issue in solc: https://github.com/ethereum/solidity/issues/2999
                    // The `mk_contract_address(this, i).call();` doesn't forward all available gas, but only GAS - 25710.
                    // As a result, when this line is executed with e.g. 30000 gas, the callee will have less than 5000 gas
                    // available and its SELFDESTRUCT operation will fail leading to no gas refund occurring.
                    // The remaining ~29000 gas left after the call is enough to update s_tail and the caller's balance.
                    // Hence tokens will have been destroyed without a commensurate gas refund.
                    // Fortunately, there is a simple workaround:
                    // Whenever you call free, freeUpTo, freeFrom, or freeUpToFrom, ensure that you pass at least
                    // 25710 + `value` * (1148 + 5722 + 150) gas. (It won't all be used)
                    function destroyChildren(uint256 value) internal {
                        uint256 tail = s_tail;
                        // tail points to slot behind the last contract in the queue
                        for (uint256 i = tail + 1; i <= tail + value; i++) {
                            mk_contract_address(this, i).call();
                        }
                
                        s_tail = tail + value;
                    }
                
                    // Frees `value` sub-tokens (e.g. cents, pennies, ...) belonging to the
                    // caller of this function by destroying `value` child contracts, which
                    // will trigger a partial gas refund.
                    // You should ensure that you pass at least 25710 + `value` * (1148 + 5722 + 150) gas
                    // when calling this function. For details, see the comment above `destroyChilden`.
                    function free(uint256 value) public returns (bool success) {
                        uint256 from_balance = s_balances[msg.sender];
                        if (value > from_balance) {
                            return false;
                        }
                
                        destroyChildren(value);
                
                        s_balances[msg.sender] = from_balance - value;
                
                        return true;
                    }
                
                    // Frees up to `value` sub-tokens. Returns how many tokens were freed.
                    // Otherwise, identical to free.
                    // You should ensure that you pass at least 25710 + `value` * (1148 + 5722 + 150) gas
                    // when calling this function. For details, see the comment above `destroyChilden`.
                    function freeUpTo(uint256 value) public returns (uint256 freed) {
                        uint256 from_balance = s_balances[msg.sender];
                        if (value > from_balance) {
                            value = from_balance;
                        }
                
                        destroyChildren(value);
                
                        s_balances[msg.sender] = from_balance - value;
                
                        return value;
                    }
                
                    // Frees `value` sub-tokens owned by address `from`. Requires that `msg.sender`
                    // has been approved by `from`.
                    // You should ensure that you pass at least 25710 + `value` * (1148 + 5722 + 150) gas
                    // when calling this function. For details, see the comment above `destroyChilden`.
                    function freeFrom(address from, uint256 value) public returns (bool success) {
                        address spender = msg.sender;
                        uint256 from_balance = s_balances[from];
                        if (value > from_balance) {
                            return false;
                        }
                
                        mapping(address => uint256) from_allowances = s_allowances[from];
                        uint256 spender_allowance = from_allowances[spender];
                        if (value > spender_allowance) {
                            return false;
                        }
                
                        destroyChildren(value);
                
                        s_balances[from] = from_balance - value;
                        from_allowances[spender] = spender_allowance - value;
                
                        return true;
                    }
                
                    // Frees up to `value` sub-tokens owned by address `from`. Returns how many tokens were freed.
                    // Otherwise, identical to `freeFrom`.
                    // You should ensure that you pass at least 25710 + `value` * (1148 + 5722 + 150) gas
                    // when calling this function. For details, see the comment above `destroyChilden`.
                    function freeFromUpTo(address from, uint256 value) public returns (uint256 freed) {
                        address spender = msg.sender;
                        uint256 from_balance = s_balances[from];
                        if (value > from_balance) {
                            value = from_balance;
                        }
                
                        mapping(address => uint256) from_allowances = s_allowances[from];
                        uint256 spender_allowance = from_allowances[spender];
                        if (value > spender_allowance) {
                            value = spender_allowance;
                        }
                
                        destroyChildren(value);
                
                        s_balances[from] = from_balance - value;
                        from_allowances[spender] = spender_allowance - value;
                
                        return value;
                    }
                }