// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

contract whiteList {
    address public anaAddress;
    address public reLockAddress;
    address public usdcAddress;
    address public ownerAddress;
    struct investInfo {
        address addr;
        uint256 amountA;
        uint256 createTime;
        bool state;
    }
    uint256 public investN;
    mapping(uint256 => investInfo) public investList;
    mapping(address => uint256) public regionLimit;
    mapping(address => address) public regionMap;
    uint256 public lockTime;
    uint256 public price;

    constructor(address addr1,address addr2,address addr3) {
        anaAddress = addr1;
        reLockAddress = addr2;
        usdcAddress = addr3;
    }
    function scyncData() public {
        (bool success, bytes memory data) = anaAddress.call(abi.encodeWithSignature("ownerAddress()"));
        require(success, "syncData failed");
        ownerAddress = abi.decode(data, (address));
    }
    function claimANA() public{
        (bool success, ) = reLockAddress.call(abi.encodeWithSignature("claim()"));
        require(success, "claim failed 1");
        (success, ) = anaAddress.call(abi.encodeWithSignature("claim()"));
        require(success, "claim failed 2");
    }
    function claimUSDC(uint256 amount) checkOwner public {
        (bool success, bytes memory data) = usdcAddress.call(abi.encodeWithSignature("transfer(address,uint256)", ownerAddress, amount));
        require(success && abi.decode(data, (bool)), "transfer failed");
    }

    modifier checkOwner{
        require(msg.sender == ownerAddress, "not owner");
        _;
    }
    
    function setLockTime(uint256 _lockTime) checkOwner public {
        require(_lockTime >= 7200*365 && _lockTime <= 7200*365*2, "_lockTime wrong");
        lockTime = _lockTime;
    }
    function setPrice(uint256 _price) checkOwner public {
        require(_price <= 50, "_price wrong");
        price = _price;
    }
    function setRegionLimit(address addr, uint256 amount) checkOwner public {
        regionLimit[addr] = amount;
    }
    function regionSetWhite(address addr) public {
        regionMap[addr] = msg.sender;
    }
    
    function invest(uint256 amountU) public {
        require(regionLimit[regionMap[msg.sender]] >= amountU, "out of limit");
        regionLimit[regionMap[msg.sender]] -= amountU;
        (bool success, bytes memory data) = usdcAddress.call(abi.encodeWithSignature("transferFrom(address,address,uint256)", msg.sender, address(this), amountU));
        require(success && abi.decode(data, (bool)), "transferFrom failed");
        investList[investN++] = investInfo(msg.sender, amountU * price, block.number, true);
    }

    function release(uint256 _n) public {
        investInfo memory i = investList[_n];
        require(block.number >= i.createTime + lockTime, "wait some times");
        require(i.state , "already release");
        investList[_n].state = false;
        (bool success, bytes memory data) = anaAddress.call(abi.encodeWithSignature("transfer(address,uint256)", i.addr, i.amountA));
        require(success && abi.decode(data, (bool)), "transfer failed");
    }
}
[{"inputs":[{"internalType":"address","name":"addr1","type":"address"},{"internalType":"address","name":"addr2","type":"address"},{"internalType":"address","name":"addr3","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"anaAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimANA","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"claimUSDC","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountU","type":"uint256"}],"name":"invest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"investList","outputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"createTime","type":"uint256"},{"internalType":"bool","name":"state","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"investN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ownerAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reLockAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"regionLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"regionMap","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"regionSetWhite","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_n","type":"uint256"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"scyncData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lockTime","type":"uint256"}],"name":"setLockTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setRegionLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"usdcAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]