Transaction Hash:
Block:
9773703 at Mar-30-2020 02:54:01 PM +UTC
Transaction Fee:
0.00059756162352 ETH
$1.49
Gas Used:
80,000 Gas / 7.469520294 Gwei
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x5A0b54D5...D3E029c4c
Miner
| (Spark Pool) | 88.164484915684696674 Eth | 88.165082477308216674 Eth | 0.00059756162352 | |
0x98c18A48...e979103fE |
11.097667581945117644 Eth
Nonce: 1924
|
11.097070020321597644 Eth
Nonce: 1925
| 0.00059756162352 |
Execution Trace
ETH 1.782785126477954938
Vyper_contract.ethToTokenSwapOutput( tokens_bought=1686000000000000000000, deadline=1585580068 )

ETH 1.782785126477954938
Vyper_contract.ethToTokenSwapOutput( tokens_bought=1686000000000000000000, deadline=1585580068 )
-
BAToken.balanceOf( _owner=0x2E642b8D59B45a1D8c5aEf716A84FF44ea665914 ) => ( balance=2299247210360452457561952 )
-
File 1 of 3: Vyper_contract
File 2 of 3: Vyper_contract
File 3 of 3: BAToken
# @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 3: 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 3 of 3: BAToken
pragma solidity ^0.4.10; /* taking ideas from FirstBlood token */ contract SafeMath { /* function assert(bool assertion) internal { */ /* if (!assertion) { */ /* throw; */ /* } */ /* } // assert no longer needed once solidity is on 0.4.10 */ function safeAdd(uint256 x, uint256 y) internal returns(uint256) { uint256 z = x + y; assert((z >= x) && (z >= y)); return z; } function safeSubtract(uint256 x, uint256 y) internal returns(uint256) { assert(x >= y); uint256 z = x - y; return z; } function safeMult(uint256 x, uint256 y) internal returns(uint256) { uint256 z = x * y; assert((x == 0)||(z/x == y)); return z; } } contract Token { uint256 public totalSupply; function balanceOf(address _owner) constant returns (uint256 balance); function transfer(address _to, uint256 _value) returns (bool success); function transferFrom(address _from, address _to, uint256 _value) returns (bool success); function approve(address _spender, uint256 _value) returns (bool success); function allowance(address _owner, address _spender) constant returns (uint256 remaining); event Transfer(address indexed _from, address indexed _to, uint256 _value); event Approval(address indexed _owner, address indexed _spender, uint256 _value); } /* ERC 20 token */ contract StandardToken is Token { function transfer(address _to, uint256 _value) returns (bool success) { if (balances[msg.sender] >= _value && _value > 0) { balances[msg.sender] -= _value; balances[_to] += _value; Transfer(msg.sender, _to, _value); return true; } else { return false; } } function transferFrom(address _from, address _to, uint256 _value) returns (bool success) { if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && _value > 0) { balances[_to] += _value; balances[_from] -= _value; allowed[_from][msg.sender] -= _value; Transfer(_from, _to, _value); return true; } else { return false; } } function balanceOf(address _owner) constant returns (uint256 balance) { return balances[_owner]; } function approve(address _spender, uint256 _value) returns (bool success) { allowed[msg.sender][_spender] = _value; Approval(msg.sender, _spender, _value); return true; } function allowance(address _owner, address _spender) constant returns (uint256 remaining) { return allowed[_owner][_spender]; } mapping (address => uint256) balances; mapping (address => mapping (address => uint256)) allowed; } contract BAToken is StandardToken, SafeMath { // metadata string public constant name = "Basic Attention Token"; string public constant symbol = "BAT"; uint256 public constant decimals = 18; string public version = "1.0"; // contracts address public ethFundDeposit; // deposit address for ETH for Brave International address public batFundDeposit; // deposit address for Brave International use and BAT User Fund // crowdsale parameters bool public isFinalized; // switched to true in operational state uint256 public fundingStartBlock; uint256 public fundingEndBlock; uint256 public constant batFund = 500 * (10**6) * 10**decimals; // 500m BAT reserved for Brave Intl use uint256 public constant tokenExchangeRate = 6400; // 6400 BAT tokens per 1 ETH uint256 public constant tokenCreationCap = 1500 * (10**6) * 10**decimals; uint256 public constant tokenCreationMin = 675 * (10**6) * 10**decimals; // events event LogRefund(address indexed _to, uint256 _value); event CreateBAT(address indexed _to, uint256 _value); // constructor function BAToken( address _ethFundDeposit, address _batFundDeposit, uint256 _fundingStartBlock, uint256 _fundingEndBlock) { isFinalized = false; //controls pre through crowdsale state ethFundDeposit = _ethFundDeposit; batFundDeposit = _batFundDeposit; fundingStartBlock = _fundingStartBlock; fundingEndBlock = _fundingEndBlock; totalSupply = batFund; balances[batFundDeposit] = batFund; // Deposit Brave Intl share CreateBAT(batFundDeposit, batFund); // logs Brave Intl fund } /// @dev Accepts ether and creates new BAT tokens. function createTokens() payable external { if (isFinalized) throw; if (block.number < fundingStartBlock) throw; if (block.number > fundingEndBlock) throw; if (msg.value == 0) throw; uint256 tokens = safeMult(msg.value, tokenExchangeRate); // check that we're not over totals uint256 checkedSupply = safeAdd(totalSupply, tokens); // return money if something goes wrong if (tokenCreationCap < checkedSupply) throw; // odd fractions won't be found totalSupply = checkedSupply; balances[msg.sender] += tokens; // safeAdd not needed; bad semantics to use here CreateBAT(msg.sender, tokens); // logs token creation } /// @dev Ends the funding period and sends the ETH home function finalize() external { if (isFinalized) throw; if (msg.sender != ethFundDeposit) throw; // locks finalize to the ultimate ETH owner if(totalSupply < tokenCreationMin) throw; // have to sell minimum to move to operational if(block.number <= fundingEndBlock && totalSupply != tokenCreationCap) throw; // move to operational isFinalized = true; if(!ethFundDeposit.send(this.balance)) throw; // send the eth to Brave International } /// @dev Allows contributors to recover their ether in the case of a failed funding campaign. function refund() external { if(isFinalized) throw; // prevents refund if operational if (block.number <= fundingEndBlock) throw; // prevents refund until sale period is over if(totalSupply >= tokenCreationMin) throw; // no refunds if we sold enough if(msg.sender == batFundDeposit) throw; // Brave Intl not entitled to a refund uint256 batVal = balances[msg.sender]; if (batVal == 0) throw; balances[msg.sender] = 0; totalSupply = safeSubtract(totalSupply, batVal); // extra safe uint256 ethVal = batVal / tokenExchangeRate; // should be safe; previous throws covers edges LogRefund(msg.sender, ethVal); // log it if (!msg.sender.send(ethVal)) throw; // if you're using a contract; make sure it works with .send gas limits } }