Address Details
contract

0x1Cb33B22118d1e60545A5241fF187f737B21732c

Artis2Launch Last Balance Update: Block #18273782
Created by 0x10205f–a28913 at 0x855c00–e8d21a

Balance

0 xDAI

(@ /xDAI)

Fetching tokens...

Contract name:
Artis2Launch




Optimization enabled
true
Compiler version
v0.7.6+commit.7338295f




Optimization runs
200
EVM Version
default




Verified at
2021-03-02 20:55:06.979506Z

Constructor Arguments

00000000000000000000000049d2bb4a247e38b817e9404246dbc48ca670783100000000000000000000000062f5caa239a97b21aa61502963cf8c33f8182e79

Arg [0] (address) : 0x49d2bb4a247e38b817e9404246dbc48ca6707831
Arg [1] (address) : 0x62f5caa239a97b21aa61502963cf8c33f8182e79

              

Contract source code

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol
// SPDX-License-Identifier: MIT AND AGPLv3
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}
// File: @openzeppelin/contracts/utils/Context.sol
// License: MIT
pragma solidity >=0.6.0 <0.8.0;
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with GSN meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address payable) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}
// File: @openzeppelin/contracts/access/Ownable.sol
// License: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor () internal {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
// File: @openzeppelin/contracts/introspection/IERC165.sol
// License: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
// File: @openzeppelin/contracts/introspection/ERC165.sol
// License: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts may inherit from this and call {_registerInterface} to declare
* their support of an interface.
*/
abstract contract ERC165 is IERC165 {
/*
* bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
*/
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
/**
* @dev Mapping of interface ids to whether or not it's supported.
*/
mapping(bytes4 => bool) private _supportedInterfaces;
constructor () internal {
// Derived contracts need only register support for their own interfaces,
// we register support for ERC165 itself here
_registerInterface(_INTERFACE_ID_ERC165);
}
/**
* @dev See {IERC165-supportsInterface}.
*
* Time complexity O(1), guaranteed to always use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return _supportedInterfaces[interfaceId];
}
/**
* @dev Registers the contract as an implementer of the interface defined by
* `interfaceId`. Support of the actual ERC165 interface is automatic and
* registering its interface id is not required.
*
* See {IERC165-supportsInterface}.
*
* Requirements:
*
* - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
*/
function _registerInterface(bytes4 interfaceId) internal virtual {
require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
}
// File: contracts/Artis2Launch.sol
// License: AGPLv3
pragma solidity 0.7.6;
// see https://github.com/ethereum/EIPs/issues/677
interface IERC677Receiver {
function onTokenTransfer(address from, uint256 amount, bytes calldata data) external returns (bool success);
}
/*
* This contract implements time constrained swapping of "old" ATS tokens to "new" ATS tokens.
* The swapping ratio is pre-defined as 5:1 initially, with a 0.2% discount per day after March 26th 2021.
* 1 year after the start of the discount period, the swapping opportunity closes
* and the contract owner can withdrawn the remaining new tokens.
* Implements ERC165 introspection for IERC677Receiver.
*/
contract Artis2Launch is IERC677Receiver, ERC165, Ownable {
IERC20 public oldToken;
IERC20 public newToken;
uint256 public constant SWAP_RATIO_NOMINATOR = 2000000;
uint256 public constant SWAP_RATIO_DENOMINATOR = 10000000;
uint256 public constant DISCOUNT_PERIOD_START = 1618531200; // Fri Apr 16 2021 00:00:00 GMT+0000
uint256 public constant DISCOUNT_PER_DAY = 20000; // daily addition to the denominator during discount period
// the swapping opportunity closes 1 year after the start of the discount period
uint256 public constant SWAP_DISABLED_AFTER = DISCOUNT_PERIOD_START + (86400 * 365);
event Swapped(uint256 oldTokenAmount, uint256 newTokenAmount);
constructor(IERC20 _oldToken, IERC20 _newToken) {
oldToken = _oldToken;
newToken = _newToken;
_registerInterface(IERC677Receiver.onTokenTransfer.selector);
}
// IERC677Receiver interface
function onTokenTransfer(address from, uint256 amount, bytes calldata)
external
override
returns (bool success)
{
// accept only known tokens
require(msg.sender == address(oldToken) || msg.sender == address(newToken), "wrong input token");
if(msg.sender == address(oldToken)) {
require(block.timestamp <= SWAP_DISABLED_AFTER, "swapping period over");
uint256 newTokenAmount = getCurrentSwapAmount(amount);
emit Swapped(amount, newTokenAmount);
return newToken.transfer(from, newTokenAmount);
}
return true;
}
// Allows the contract owner to withdraw alien tokens from the contract.
function withdrawAlienTokens(IERC20 token)
external
onlyOwner
{
require(token != oldToken && token != newToken, "not an alien token");
require(token.balanceOf(address(this)) > 0, "no such token owned");
token.transfer(msg.sender, token.balanceOf(address(this)));
}
// After the end of the swapping period, the owner can withdraw remaining new tokens to a given address.
function withdrawRemainingNewTokensTo(address receiver)
external
onlyOwner
{
require(block.timestamp > SWAP_DISABLED_AFTER, "withdrawal not yet allowed");
newToken.transfer(receiver, newToken.balanceOf(address(this)));
}
// Returns the amount of new tokens a given amount of old tokens would be converted to at the current time.
// During the discount period, the discount increases by 0.2% every 24 hours relative to the initial ratio.
function getCurrentSwapAmount(uint256 amount)
public
view
returns(uint256)
{
return getSwapAmountAt(amount, block.timestamp);
}
function getSwapAmountAt(uint256 amount, uint256 timestamp)
public
view
returns(uint256)
{
uint256 discountTimeframe = timestamp > DISCOUNT_PERIOD_START ? timestamp - DISCOUNT_PERIOD_START : 0;
uint256 nrDiscountDays = discountTimeframe / 86400;
return timestamp <= SWAP_DISABLED_AFTER ?
amount * SWAP_RATIO_NOMINATOR / (SWAP_RATIO_DENOMINATOR + (nrDiscountDays* DISCOUNT_PER_DAY)) :
0;
}
}

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_oldToken","internalType":"contract IERC20"},{"type":"address","name":"_newToken","internalType":"contract IERC20"}]},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Swapped","inputs":[{"type":"uint256","name":"oldTokenAmount","internalType":"uint256","indexed":false},{"type":"uint256","name":"newTokenAmount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"DISCOUNT_PERIOD_START","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"DISCOUNT_PER_DAY","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"SWAP_DISABLED_AFTER","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"SWAP_RATIO_DENOMINATOR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"SWAP_RATIO_NOMINATOR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getCurrentSwapAmount","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getSwapAmountAt","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"timestamp","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IERC20"}],"name":"newToken","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IERC20"}],"name":"oldToken","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"success","internalType":"bool"}],"name":"onTokenTransfer","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"bytes","name":"","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"supportsInterface","inputs":[{"type":"bytes4","name":"interfaceId","internalType":"bytes4"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawAlienTokens","inputs":[{"type":"address","name":"token","internalType":"contract IERC20"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawRemainingNewTokensTo","inputs":[{"type":"address","name":"receiver","internalType":"address"}]}]
            

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106101005760003560e01c8063a1a41bdc11610097578063bfe3a47811610066578063bfe3a47814610296578063c42bd05a1461029e578063e63db398146102a6578063f2fde38b146102c957610100565b8063a1a41bdc146101f9578063a4c0ed3614610201578063b31c710a14610286578063be2983971461028e57610100565b806363e1792e116100d357806363e1792e1461019f578063715018a6146101c55780638da5cb5b146101cd57806398e46658146101f157610100565b806301ffc9a71461010557806324b10068146101405780634292156d1461015a5780634863458114610182575b600080fd5b61012c6004803603602081101561011b57600080fd5b50356001600160e01b0319166102ef565b604080519115158252519081900360200190f35b61014861030e565b60408051918252519081900360200190f35b6101806004803603602081101561017057600080fd5b50356001600160a01b0316610315565b005b6101486004803603602081101561019857600080fd5b50356105b3565b610180600480360360208110156101b557600080fd5b50356001600160a01b03166105c5565b6101806106d3565b6101d561077f565b604080516001600160a01b039092168252519081900360200190f35b61014861078e565b610148610794565b61012c6004803603606081101561021757600080fd5b6001600160a01b038235169160208101359181019060608101604082013564010000000081111561024757600080fd5b82018360208201111561025957600080fd5b8035906020019184600183028401116401000000008311171561027b57600080fd5b50909250905061079c565b6101d561094a565b610148610959565b610148610960565b6101d5610968565b610148600480360360408110156102bc57600080fd5b5080359060200135610977565b610180600480360360208110156102df57600080fd5b50356001600160a01b03166109d1565b6001600160e01b03191660009081526020819052604090205460ff1690565b621e848081565b61031d610ad4565b6001600160a01b031661032e61077f565b6001600160a01b031614610377576040805162461bcd60e51b81526020600482018190526024820152600080516020610aff833981519152604482015290519081900360640190fd5b6002546001600160a01b038281169116148015906103a357506003546001600160a01b03828116911614155b6103e9576040805162461bcd60e51b81526020600482015260126024820152713737ba1030b71030b634b2b7103a37b5b2b760711b604482015290519081900360640190fd5b6000816001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561043857600080fd5b505afa15801561044c573d6000803e3d6000fd5b505050506040513d602081101561046257600080fd5b5051116104ac576040805162461bcd60e51b81526020600482015260136024820152721b9bc81cdd58da081d1bdad95b881bdddb9959606a1b604482015290519081900360640190fd5b806001600160a01b031663a9059cbb33836001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561050957600080fd5b505afa15801561051d573d6000803e3d6000fd5b505050506040513d602081101561053357600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091525160448083019260209291908290030181600087803b15801561058457600080fd5b505af1158015610598573d6000803e3d6000fd5b505050506040513d60208110156105ae57600080fd5b505050565b60006105bf8242610977565b92915050565b6105cd610ad4565b6001600160a01b03166105de61077f565b6001600160a01b031614610627576040805162461bcd60e51b81526020600482018190526024820152600080516020610aff833981519152604482015290519081900360640190fd5b63625a0700421161067f576040805162461bcd60e51b815260206004820152601a60248201527f7769746864726177616c206e6f742079657420616c6c6f776564000000000000604482015290519081900360640190fd5b600354604080516370a0823160e01b815230600482015290516001600160a01b039092169163a9059cbb91849184916370a08231916024808301926020929190829003018186803b15801561050957600080fd5b6106db610ad4565b6001600160a01b03166106ec61077f565b6001600160a01b031614610735576040805162461bcd60e51b81526020600482018190526024820152600080516020610aff833981519152604482015290519081900360640190fd5b6001546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600180546001600160a01b0319169055565b6001546001600160a01b031690565b614e2081565b636078d38081565b6002546000906001600160a01b03163314806107c257506003546001600160a01b031633145b610807576040805162461bcd60e51b81526020600482015260116024820152703bb937b7339034b7383aba103a37b5b2b760791b604482015290519081900360640190fd5b6002546001600160a01b031633141561093e5763625a070042111561086a576040805162461bcd60e51b815260206004820152601460248201527339bbb0b83834b733903832b934b7b21037bb32b960611b604482015290519081900360640190fd5b6000610875856105b3565b604080518781526020810183905281519293507f5a6443be634d8594e0dff76c972a6a74f88bf761fb6e334d88dd979516f3bc8f929081900390910190a16003546040805163a9059cbb60e01b81526001600160a01b038981166004830152602482018590529151919092169163a9059cbb9160448083019260209291908290030181600087803b15801561090957600080fd5b505af115801561091d573d6000803e3d6000fd5b505050506040513d602081101561093357600080fd5b505191506109429050565b5060015b949350505050565b6002546001600160a01b031681565b6298968081565b63625a070081565b6003546001600160a01b031681565b600080636078d380831161098c576000610994565b636078d38083035b905062015180810463625a07008411156109af5760006109c8565b614e2081026298968001621e84808602816109c657fe5b045b95945050505050565b6109d9610ad4565b6001600160a01b03166109ea61077f565b6001600160a01b031614610a33576040805162461bcd60e51b81526020600482018190526024820152600080516020610aff833981519152604482015290519081900360640190fd5b6001600160a01b038116610a785760405162461bcd60e51b8152600401808060200182810382526026815260200180610ad96026913960400191505060405180910390fd5b6001546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b339056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a2646970667358221220aa3a1f312454eae3fc789a2be74906f01fd16df00d63ceaf6430a65c0004274c64736f6c63430007060033