账户
0x6d...3df2
0x6D...3dF2

0x6D...3dF2

$500
此合同的源代码已经过验证!
合同元数据
编译器
0.8.6+commit.11564f7e
语言
Solidity
合同源代码
文件 1 的 1:Swapper.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.0;

/**
 * @title Swap
 * @dev Main Swap contract that burns old token and mints new token for given user
 */

contract Owned {
        address public owner;      

        constructor() {
            owner = msg.sender;
        }

        modifier onlyOwner {
            assert(msg.sender == owner);
            _;
        }
        
        /* This function is used to transfer adminship to new owner
         * @param  _newOwner - address of new admin or owner        
         */

        function transferOwnership(address _newOwner) onlyOwner public {
            assert(_newOwner != address(0)); 
            owner = _newOwner;
        }          
}

contract Swapper is Owned
{
    
    ERC20 public oldToken;
    ERC20 public newToken;
    Burner public  burner;
    
    event SwapExecuted(address user, uint256 amount);

    struct VestingUnit {
        uint256 amount;
        uint256 timestamp;
    }
        
    uint256 public approvalDeadline;

    mapping(address => VestingUnit[]) public holdersVestingData;
    
    function claim() public {
        VestingUnit[] memory vestingUnits = holdersVestingData[msg.sender];
        uint sum = 0;
        for(uint i = 0; i < vestingUnits.length; i++) {
            uint256 finalClaimableTime = vestingUnits[i].timestamp + findTimeMultipler(i) * 30 days + 2 weeks;
            if(finalClaimableTime < block.timestamp){
                continue;
            }
            if(vestingUnits[i].amount > 0 && vestingUnits[i].timestamp < block.timestamp) {
                sum += vestingUnits[i].amount;
                delete holdersVestingData[msg.sender][i];
            }
        }
        newToken.transfer(msg.sender, sum);
    }
    
    function amountClaimable(address holder) public view returns(uint256) {
        VestingUnit[] memory vestingUnits = holdersVestingData[holder];
        uint sum = 0;
        for(uint i = 0; i < vestingUnits.length; i++) {
             uint256 finalClaimableTime = vestingUnits[i].timestamp + findTimeMultipler(i) * 30 days + 2 weeks;
            if(finalClaimableTime < block.timestamp){
                continue;
            }
            if(vestingUnits[i].amount > 0 && vestingUnits[i].timestamp < block.timestamp) {
                sum += vestingUnits[i].amount;
            }
        }
        return sum;
    }
     
    constructor(
        address _oldToken,
        address _newToken,
        address _burner,
        uint256 _approvalDeadline

    ) {
        approvalDeadline = _approvalDeadline;
        oldToken = ERC20(_oldToken);
        newToken = ERC20(_newToken);
        burner = Burner(_burner);

    }


    function updateApprovalDeadline(uint256 _approvalDeadline) onlyOwner public {
        approvalDeadline = _approvalDeadline;
    }
    
    function energencyWithdraw(uint256 _amount) onlyOwner public {
        newToken.transfer(msg.sender,_amount);
    }
    
	function SwapNow(uint256 _val) public {
	    require(approvalDeadline > block.timestamp,"deadline reached");
	    require(oldToken.allowance(msg.sender, address(this)) >= _val,"allowance lower"); 
	    oldToken.transferFrom(msg.sender, address(burner), _val);
	    burner.burn(_val);
	    newToken.transfer(msg.sender, _val / 10);
	    
	    setVestingData(_val);

	    emit SwapExecuted(msg.sender, _val);
	}
	
	function calculateCutPerMonth(uint256 totalAmount) private pure returns (uint256){
	    return totalAmount * 75/1000;
	}
	
	
	function setVestingData(uint256 _val) private {
	    	  
	    uint256 amount = calculateCutPerMonth(_val);
	    uint256 finalChunkAmount = _val - _val/10;
	    for(uint256 i=0; i < 11; i++){
	        uint256 vestingTimestamp = block.timestamp + 90 days + 30 days * i;
	        VestingUnit memory vestingData  = VestingUnit({amount:amount,timestamp:vestingTimestamp});
	        holdersVestingData[msg.sender].push(vestingData);
	        finalChunkAmount -= amount;
	    }
	    
	    holdersVestingData[msg.sender].push(VestingUnit({amount:finalChunkAmount,timestamp:block.timestamp + 90 days + 30 days * 11}));
	}
	
	
	function findTimeMultipler(uint256 i) private pure returns(uint256){
	    if((i+1)%12 == 0){
	        return 0 ;
	    }
	    else{
	        return 12 - (i+1)%12;
	    }
	}
	

	function remainingClaim(address _holder) view public returns(uint256) {
	    VestingUnit[] memory vestingUnits = holdersVestingData[_holder];
        uint sum = 0;
        for(uint i = 0; i < vestingUnits.length; i++) {
            if(vestingUnits[i].amount > 0) {
                sum += vestingUnits[i].amount;
            }
        }
        return sum;
	}
}
contract Burner is Owned {
    ERC20 oldToken;
    
    function returnOwnership(address _newOwner) public onlyOwner {
        oldToken.transferOwnership(_newOwner);
    }
    
    constructor(address _oldToken) {
        oldToken = ERC20(_oldToken);
    }
    
    function burn(uint256 _val) public {
        oldToken.burn(_val);
    }
}


interface ERC20 {
    function transferOwnership(address _newOwner) external;
    
    function transferFrom(
         address _from,
         address _to,
         uint256 _amount
     ) external returns (bool success);
    
    
    function allowance(address owner, address spender) external view returns (uint256);
    
    function burn(uint256 _value) external;
    
    function transfer(address recipient, uint256 amount) external returns (bool);

}
设置
{
  "compilationTarget": {
    "Swapper.sol": "Swapper"
  },
  "evmVersion": "berlin",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "remappings": []
}
ABI
[{"inputs":[{"internalType":"address","name":"_oldToken","type":"address"},{"internalType":"address","name":"_newToken","type":"address"},{"internalType":"address","name":"_burner","type":"address"},{"internalType":"uint256","name":"_approvalDeadline","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"SwapExecuted","type":"event"},{"inputs":[{"internalType":"uint256","name":"_val","type":"uint256"}],"name":"SwapNow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"holder","type":"address"}],"name":"amountClaimable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"approvalDeadline","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burner","outputs":[{"internalType":"contract Burner","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"energencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"holdersVestingData","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"newToken","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oldToken","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_holder","type":"address"}],"name":"remainingClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_approvalDeadline","type":"uint256"}],"name":"updateApprovalDeadline","outputs":[],"stateMutability":"nonpayable","type":"function"}]