ETH Price: $2,001.22 (-0.12%)

Transaction Decoder

Block:
21212831 at Nov-18-2024 06:32:23 AM +UTC
Transaction Fee:
0.002432991384204288 ETH $4.87
Gas Used:
222,672 Gas / 10.926346304 Gwei

Emitted Events:

200 REXAS_FINANCE.Transfer( from=[Receiver] Rexas_Presale, to=[Sender] 0xa5414a23e3502f9b680f63be4d64753e8559b2d0, value=2327301037500000000000 )
201 Rexas_Presale.TokensBought( user=[Sender] 0xa5414a23e3502f9b680f63be4d64753e8559b2d0, id=6, purchaseToken=0x00000000...000000000, tokensBought=2327301037500000000000, amountPaid=59500000000000004, timestamp=1731911543 )

Account State Difference:

  Address   Before After State Difference Code
0x01FB3DCb...7873F8721 2,073.746575183986162901 Eth2,073.806075183986162905 Eth0.059500000000000004
(beaverbuild)
20.435876651601849685 Eth20.436108501029443045 Eth0.00023184942759336
0x9eAeBd7E...b550e224c
0xa5414A23...e8559b2d0
0.067 Eth
Nonce: 0
0.005067008615795708 Eth
Nonce: 1
0.061932991384204292
0xa9502665...615fB16F6
(Rexas Finance: Presale Contract)

Execution Trace

ETH 0.059500000000000004 Rexas_Presale.CALL( )
  • EACAggregatorProxy.STATICCALL( )
    • 0x7d4e742018fb52e48b08be73d041c18b21de6fb5.STATICCALL( )
    • EACAggregatorProxy.STATICCALL( )
      • 0x7d4e742018fb52e48b08be73d041c18b21de6fb5.STATICCALL( )
      • ETH 0.059500000000000004 0x01fb3dcb4d5b3942ade0de7685fc86c7873f8721.CALL( )
      • REXAS_FINANCE.transfer( recipient=0xa5414A23E3502F9b680f63bE4D64753e8559b2d0, amount=2327301037500000000000 ) => ( True )
        File 1 of 3: Rexas_Presale
        // 
        // ░▒▓███████▓▒░░▒▓█▓▒░░▒▓█▓▒░░▒▓███████▓▒░ 
        // ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░        
        // ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░        
        // ░▒▓███████▓▒░ ░▒▓██████▓▒░ ░▒▓██████▓▒░  
        // ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░      ░▒▓█▓▒░ 
        // ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░      ░▒▓█▓▒░ 
        // ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓███████▓▒░  
        //                                      
        // Rexas Finance Presale
        // Website: https://rexas.com
        // Twitter/X: https://x.com/rexasfinance
        // Telegram: https://t.me/rexasfinance
        // 
        
        
        //SPDX-License-Identifier: MIT
        pragma solidity ^0.8.20;
        
        abstract contract ReentrancyGuard {
            uint256 private constant _NOT_ENTERED = 1;
            uint256 private constant _ENTERED = 2;
        
            uint256 private _status;
        
            constructor() {
                _status = _NOT_ENTERED;
            }
        
            modifier nonReentrant() {
                _nonReentrantBefore();
                _;
                _nonReentrantAfter();
            }
        
            function _nonReentrantBefore() private {
                require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
        
                _status = _ENTERED;
            }
        
            function _nonReentrantAfter() private {
                _status = _NOT_ENTERED;
            }
        }
        
        abstract contract Context {
            function _msgSender() internal view virtual returns (address) {
                return msg.sender;
            }
        
            function _msgData() internal view virtual returns (bytes calldata) {
                return msg.data;
            }
        }
        
        abstract contract Ownable is Context {
            address private _owner;
        
            event OwnershipTransferred(
                address indexed previousOwner,
                address indexed newOwner
            );
        
            constructor() {
                _transferOwnership(_msgSender());
            }
        
            modifier onlyOwner() {
                _checkOwner();
                _;
            }
        
            function owner() public view virtual returns (address) {
                return _owner;
            }
        
            function _checkOwner() internal view virtual {
                require(owner() == _msgSender(), "Ownable: caller is not the owner");
            }
        
            function renounceOwnership() public virtual onlyOwner {
                _transferOwnership(address(0));
            }
        
            function transferOwnership(address newOwner) public virtual onlyOwner {
                require(
                    newOwner != address(0),
                    "Ownable: new owner is the zero address"
                );
                _transferOwnership(newOwner);
            }
        
            function _transferOwnership(address newOwner) internal virtual {
                address oldOwner = _owner;
                _owner = newOwner;
                emit OwnershipTransferred(oldOwner, newOwner);
            }
        }
        
        library Address {
            function isContract(address account) internal view returns (bool) {
                return account.code.length > 0;
            }
        
            function sendValue(address payable recipient, uint256 amount) internal {
                require(
                    address(this).balance >= amount,
                    "Address: insufficient balance"
                );
        
                (bool success, ) = recipient.call{value: amount}("");
                require(
                    success,
                    "Address: unable to send value, recipient may have reverted"
                );
            }
        
            function functionCall(address target, bytes memory data)
                internal
                returns (bytes memory)
            {
                return
                    functionCallWithValue(
                        target,
                        data,
                        0,
                        "Address: low-level call failed"
                    );
            }
        
            function functionCall(
                address target,
                bytes memory data,
                string memory errorMessage
            ) internal returns (bytes memory) {
                return functionCallWithValue(target, data, 0, errorMessage);
            }
        
            function functionCallWithValue(
                address target,
                bytes memory data,
                uint256 value
            ) internal returns (bytes memory) {
                return
                    functionCallWithValue(
                        target,
                        data,
                        value,
                        "Address: low-level call with value failed"
                    );
            }
        
            function functionCallWithValue(
                address target,
                bytes memory data,
                uint256 value,
                string memory errorMessage
            ) internal returns (bytes memory) {
                require(
                    address(this).balance >= value,
                    "Address: insufficient balance for call"
                );
                (bool success, bytes memory returndata) = target.call{value: value}(
                    data
                );
                return
                    verifyCallResultFromTarget(
                        target,
                        success,
                        returndata,
                        errorMessage
                    );
            }
        
            function functionStaticCall(address target, bytes memory data)
                internal
                view
                returns (bytes memory)
            {
                return
                    functionStaticCall(
                        target,
                        data,
                        "Address: low-level static call failed"
                    );
            }
        
            function functionStaticCall(
                address target,
                bytes memory data,
                string memory errorMessage
            ) internal view returns (bytes memory) {
                (bool success, bytes memory returndata) = target.staticcall(data);
                return
                    verifyCallResultFromTarget(
                        target,
                        success,
                        returndata,
                        errorMessage
                    );
            }
        
            function functionDelegateCall(address target, bytes memory data)
                internal
                returns (bytes memory)
            {
                return
                    functionDelegateCall(
                        target,
                        data,
                        "Address: low-level delegate call failed"
                    );
            }
        
            function functionDelegateCall(
                address target,
                bytes memory data,
                string memory errorMessage
            ) internal returns (bytes memory) {
                (bool success, bytes memory returndata) = target.delegatecall(data);
                return
                    verifyCallResultFromTarget(
                        target,
                        success,
                        returndata,
                        errorMessage
                    );
            }
        
            function verifyCallResultFromTarget(
                address target,
                bool success,
                bytes memory returndata,
                string memory errorMessage
            ) internal view returns (bytes memory) {
                if (success) {
                    if (returndata.length == 0) {
                        require(isContract(target), "Address: call to non-contract");
                    }
                    return returndata;
                } else {
                    _revert(returndata, errorMessage);
                }
            }
        
            function verifyCallResult(
                bool success,
                bytes memory returndata,
                string memory errorMessage
            ) internal pure returns (bytes memory) {
                if (success) {
                    return returndata;
                } else {
                    _revert(returndata, errorMessage);
                }
            }
        
            function _revert(bytes memory returndata, string memory errorMessage)
                private
                pure
            {
                if (returndata.length > 0) {
                    assembly {
                        let returndata_size := mload(returndata)
                        revert(add(32, returndata), returndata_size)
                    }
                } else {
                    revert(errorMessage);
                }
            }
        }
        
        interface IERC20 {
            event Transfer(address indexed from, address indexed to, uint256 value);
        
            event Approval(
                address indexed owner,
                address indexed spender,
                uint256 value
            );
        
            function totalSupply() external view returns (uint256);
        
            function balanceOf(address account) external view returns (uint256);
        
            function transfer(address to, uint256 amount) external returns (bool);
        
            function allowance(address owner, address spender)
                external
                view
                returns (uint256);
        
            function approve(address spender, uint256 amount) external returns (bool);
        
            function transferFrom(
                address from,
                address to,
                uint256 amount
            ) external returns (bool);
        }
        
        interface IERC20Metadata is IERC20 {
            function name() external view returns (string memory);
        
            function symbol() external view returns (string memory);
        
            function decimals() external view returns (uint8);
        }
        
        interface Aggregator {
            function latestRoundData()
                external
                view
                returns (
                    uint80 roundId,
                    int256 answer,
                    uint256 startedAt,
                    uint256 updatedAt,
                    uint80 answeredInRound
                );
        }
        
        contract Rexas_Presale is ReentrancyGuard, Ownable {
            uint256 public overalllRaised;
            uint256 public presaleId;
            uint256 public USDT_MULTIPLIER;
            uint256 public ETH_MULTIPLIER;
            address public fundReceiver;
            uint256 public uniqueBuyers;
        
            struct PresaleData {
                uint256 startTime;
                uint256 endTime;
                uint256 price;
                uint256 nextStagePrice;
                uint256 Sold;
                uint256 tokensToSell;
                uint256 UsdtHardcap;
                uint256 amountRaised;
                bool Active;
            }
        
            struct UserData {
                uint256 investedAmount;
                uint256 receivedTokenAmount;
            }
        
            IERC20Metadata public USDTInterface;
            IERC20Metadata public USDCInterface;
            Aggregator internal aggregatorInterface;
        
            mapping(uint256 => bool) public paused;
            mapping(uint256 => PresaleData) public presale;
            mapping(address => mapping(uint256 => UserData)) public userData;
            mapping(address => bool) public isExcludeMinToken;
            mapping(address => bool) public isBlackList;
            mapping(address => bool) public isExist;
        
            uint256 public MinTokenTobuy;
            uint256 public currentSale;
            address public SaleToken;
        
            event PresaleCreated(
                uint256 indexed _id,
                uint256 _totalTokens,
                uint256 _startTime,
                uint256 _endTime
            );
        
            event PresaleUpdated(
                bytes32 indexed key,
                uint256 prevValue,
                uint256 newValue,
                uint256 timestamp
            );
        
            event TokensBought(
                address indexed user,
                uint256 indexed id,
                address indexed purchaseToken,
                uint256 tokensBought,
                uint256 amountPaid,
                uint256 timestamp
            );
        
            event TokensClaimed(
                address indexed user,
                uint256 indexed id,
                uint256 amount,
                uint256 timestamp
            );
        
            event PresalePaused(uint256 indexed id, uint256 timestamp);
        
            event PresaleUnpaused(uint256 indexed id, uint256 timestamp);
        
            constructor(
                address _oracle,
                address _usdt,
                address _usdc,
                address _SaleToken,
                uint256 _MinTokenTobuy
            ) {
                aggregatorInterface = Aggregator(_oracle);
                SaleToken = _SaleToken;
                MinTokenTobuy = _MinTokenTobuy;
                USDTInterface = IERC20Metadata(_usdt);
                USDCInterface = IERC20Metadata(_usdc);
                ETH_MULTIPLIER = (10**18);
                USDT_MULTIPLIER = (10**6);
                fundReceiver = msg.sender;
            }
        
            function createPresale(
                uint256 _price,
                uint256 _nextStagePrice,
                uint256 _tokensToSell,
                uint256 _UsdtHardcap
            ) external onlyOwner {
                require(_price > 0, "Zero price");
                require(_tokensToSell > 0, "Zero tokens to sell");
        
                presaleId++;
        
                presale[presaleId] = PresaleData(
                    0,
                    0,
                    _price,
                    _nextStagePrice,
                    0,
                    _tokensToSell,
                    _UsdtHardcap,
                    0,
                    false
                );
        
                emit PresaleCreated(presaleId, _tokensToSell, 0, 0);
            }
        
            function setPresaleStage(uint256 _id) public onlyOwner {
                require(presale[_id].tokensToSell > 0, "Presale don't exist");
                if (currentSale != 0) {
                    presale[currentSale].endTime = block.timestamp;
                    presale[currentSale].Active = false;
                }
                presale[_id].startTime = block.timestamp;
                presale[_id].Active = true;
                currentSale = _id;
            }
        
            function updatePresale(
                uint256 _id,
                uint256 _price,
                uint256 _nextStagePrice,
                uint256 _tokensToSell,
                uint256 _Hardcap
            ) external onlyOwner {
                require(_price > 0, "Zero price");
                require(_tokensToSell > 0, "Zero tokens to sell");
                require(_Hardcap > 0, "Zero harcap");
                presale[_id].price = _price;
                presale[_id].nextStagePrice = _nextStagePrice;
                presale[_id].tokensToSell = _tokensToSell;
                presale[_id].UsdtHardcap = _Hardcap;
            }
        
            function changeFundWallet(address _wallet) external onlyOwner {
                require(_wallet != address(0), "Invalid parameters");
                fundReceiver = _wallet;
            }
        
            function changeUSDTToken(address _newAddress) external onlyOwner {
                require(_newAddress != address(0), "Zero token address");
                USDTInterface = IERC20Metadata(_newAddress);
            }
        
            function changeUSDCToken(address _newAddress) external onlyOwner {
                require(_newAddress != address(0), "Zero token address");
                USDCInterface = IERC20Metadata(_newAddress);
            }
        
            function pausePresale(uint256 _id) external checkPresaleId(_id) onlyOwner {
                require(!paused[_id], "Already paused");
                paused[_id] = true;
                emit PresalePaused(_id, block.timestamp);
            }
        
            function unPausePresale(uint256 _id)
                external
                checkPresaleId(_id)
                onlyOwner
            {
                require(paused[_id], "Not paused");
                paused[_id] = false;
                emit PresaleUnpaused(_id, block.timestamp);
            }
        
            function getLatestPrice() public view returns (uint256) {
                (, int256 price, , , ) = aggregatorInterface.latestRoundData();
                price = (price * (10**10));
                return uint256(price);
            }
        
            modifier checkPresaleId(uint256 _id) {
                require(_id > 0 && _id == currentSale, "Invalid presale id");
                _;
            }
        
            modifier checkSaleState(uint256 _id, uint256 amount) {
                require(presale[_id].Active == true, "preSAle not Active");
                require(
                    amount > 0 &&
                        amount <= presale[_id].tokensToSell - presale[_id].Sold,
                    "Invalid sale amount"
                );
                _;
            }
        
            function ExcludeAccouctFromMinBuy(address _user, bool _status)
                external
                onlyOwner
            {
                isExcludeMinToken[_user] = _status;
            }
        
            function blackListUser(address _user, bool _value) public onlyOwner {
                isBlackList[_user] = _value;
            }
        
            function buyWithUSDT(uint256 usdAmount)
                external
                checkPresaleId(currentSale)
                checkSaleState(currentSale, usdToTokens(currentSale, usdAmount))
                nonReentrant
                returns (bool)
            {
                require(!paused[currentSale], "Presale paused");
                require(
                    presale[currentSale].Active == true,
                    "Presale is not active yet"
                );
                require(!isBlackList[msg.sender], "Account is blackListed");
                require(
                    presale[currentSale].amountRaised + usdAmount <=
                        presale[currentSale].UsdtHardcap,
                    "Amount should be less than leftHardcap"
                );
                if (!isExist[msg.sender]) {
                    isExist[msg.sender] = true;
                    uniqueBuyers++;
                }
                uint256 tokens = usdToTokens(currentSale, usdAmount);
                presale[currentSale].Sold += tokens;
                presale[currentSale].amountRaised += usdAmount;
                overalllRaised += usdAmount;
        
                if (isExcludeMinToken[msg.sender] == false) {
                    require(tokens >= MinTokenTobuy, "Less than min amount");
                }
                userData[_msgSender()][currentSale].investedAmount += usdAmount;
                userData[_msgSender()][currentSale].receivedTokenAmount += tokens;
                
                uint256 ourAllowance = USDTInterface.allowance(
                    _msgSender(),
                    address(this)
                );
                require(usdAmount <= ourAllowance, "Make sure to add enough allowance");
                (bool success, ) = address(USDTInterface).call(
                    abi.encodeWithSignature(
                        "transferFrom(address,address,uint256)",
                        _msgSender(),
                        fundReceiver,
                        usdAmount
                    )
                );
                require(success, "Token payment failed");
                bool status = IERC20(SaleToken).transfer(
                        _msgSender(),
                        tokens
                    );
                require(status, "Token transfer failed");
                
                emit TokensBought(
                    _msgSender(),
                    currentSale,
                    address(USDTInterface),
                    tokens,
                    usdAmount,
                    block.timestamp
                );
                return true;
            }
        
            function buyWithUSDC(uint256 usdcAmount)
                external
                checkPresaleId(currentSale)
                checkSaleState(currentSale, usdToTokens(currentSale, usdcAmount))
                nonReentrant
                returns (bool)
            {
                require(!paused[currentSale], "Presale paused");
                require(
                    presale[currentSale].Active == true,
                    "Presale is not active yet"
                );
                require(
                    presale[currentSale].amountRaised + usdcAmount <=
                        presale[currentSale].UsdtHardcap,
                    "Amount should be less than leftHardcap"
                );
                require(!isBlackList[msg.sender], "Account is blackListed");
                if (!isExist[msg.sender]) {
                    isExist[msg.sender] = true;
                    uniqueBuyers++;
                }
                uint256 tokens = usdToTokens(currentSale, usdcAmount);
                presale[currentSale].Sold += tokens;
                presale[currentSale].amountRaised += usdcAmount;
                overalllRaised += usdcAmount;
        
                if (isExcludeMinToken[msg.sender] == false) {
                    require(tokens >= MinTokenTobuy, "Less than min amount");
                }
                userData[_msgSender()][currentSale].investedAmount += usdcAmount;
                userData[_msgSender()][currentSale].receivedTokenAmount += tokens;
        
                uint256 ourAllowance = USDTInterface.allowance(
                    _msgSender(),
                    address(this)
                );
                require(
                    usdcAmount <= ourAllowance,
                    "Make sure to add enough allowance"
                );
                (bool success, ) = address(USDCInterface).call(
                    abi.encodeWithSignature(
                        "transferFrom(address,address,uint256)",
                        _msgSender(),
                        fundReceiver,
                        usdcAmount
                    )
                );
                require(success, "Token payment failed");
                bool status = IERC20(SaleToken).transfer(
                        _msgSender(),
                        tokens
                    );
                require(status, "Token transfer failed");
        
                emit TokensBought(
                    _msgSender(),
                    currentSale,
                    address(USDTInterface),
                    tokens,
                    usdcAmount,
                    block.timestamp
                );
                return true;
            }
        
            function buyWithEth()
                external
                payable
                checkPresaleId(currentSale)
                checkSaleState(currentSale, ethToTokens(currentSale, msg.value))
                nonReentrant
                returns (bool)
            {
                uint256 usdAmount = (msg.value * getLatestPrice() * USDT_MULTIPLIER) /
                    (ETH_MULTIPLIER * ETH_MULTIPLIER);
                require(
                    presale[currentSale].amountRaised + usdAmount <=
                        presale[currentSale].UsdtHardcap,
                    "Amount should be less than leftHardcap"
                );
                require(!isBlackList[msg.sender], "Account is blackListed");
                require(!paused[currentSale], "Presale paused");
                require(
                    presale[currentSale].Active == true,
                    "Presale is not active yet"
                );
                if (!isExist[msg.sender]) {
                    isExist[msg.sender] = true;
                    uniqueBuyers++;
                }
        
                uint256 tokens = usdToTokens(currentSale, usdAmount);
                if (isExcludeMinToken[msg.sender] == false) {
                    require(tokens >= MinTokenTobuy, "Insufficient Amount!");
                }
                presale[currentSale].Sold += tokens;
                presale[currentSale].amountRaised += usdAmount;
                overalllRaised += usdAmount;
                userData[_msgSender()][currentSale].investedAmount += usdAmount;
                userData[_msgSender()][currentSale].receivedTokenAmount += tokens;
                
                sendValue(payable(fundReceiver), msg.value);
                bool status = IERC20(SaleToken).transfer(
                        _msgSender(),
                        tokens
                    );
                require(status, "Token transfer failed");
        
                emit TokensBought(
                    _msgSender(),
                    currentSale,
                    address(0),
                    tokens,
                    msg.value,
                    block.timestamp
                );
                return true;
            }
        
            function ethBuyHelper(uint256 _id, uint256 amount)
                external
                view
                returns (uint256 ethAmount)
            {
                uint256 usdPrice = (amount * presale[_id].price);
                ethAmount =
                    (usdPrice * ETH_MULTIPLIER) /
                    (getLatestPrice() * 10**IERC20Metadata(SaleToken).decimals());
            }
        
            function usdBuyHelper(uint256 _id, uint256 amount)
                external
                view
                returns (uint256 usdPrice)
            {
                usdPrice =
                    (amount * presale[_id].price) /
                    10**IERC20Metadata(SaleToken).decimals();
            }
        
            function ethToTokens(uint256 _id, uint256 amount)
                public
                view
                returns (uint256 _tokens)
            {
                uint256 usdAmount = (amount * getLatestPrice() * USDT_MULTIPLIER) /
                    (ETH_MULTIPLIER * ETH_MULTIPLIER);
                _tokens = usdToTokens(_id, usdAmount);
            }
        
            function usdToTokens(uint256 _id, uint256 amount)
                public
                view
                returns (uint256 _tokens)
            {
                _tokens = (amount * presale[_id].price) / USDT_MULTIPLIER;
            }
        
            function sendValue(address payable recipient, uint256 amount) internal {
                require(address(this).balance >= amount, "Low balance");
                (bool success, ) = recipient.call{value: amount}("");
                require(success, "ETH Payment failed");
            }
        
            function WithdrawTokens(address _token, uint256 amount) external onlyOwner {
                IERC20(_token).transfer(fundReceiver, amount);
            }
        
            function WithdrawContractFunds(uint256 amount) external onlyOwner {
                sendValue(payable(fundReceiver), amount);
            }
        
            function ChangeSaleToken(address _token) public onlyOwner {
                SaleToken = _token;
            }
        
            function ChangeMinTokenToBuy(uint256 _amount) public onlyOwner {
                MinTokenTobuy = _amount;
            }
        
            function ChangeOracleAddress(address _oracle) public onlyOwner {
                aggregatorInterface = Aggregator(_oracle);
            }
        
            function blockTimeStamp() public view returns(uint256) {
                return block.timestamp;
            }
        }

        File 2 of 3: REXAS_FINANCE
        // 
        // ░▒▓███████▓▒░░▒▓█▓▒░░▒▓█▓▒░░▒▓███████▓▒░ 
        // ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░        
        // ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░        
        // ░▒▓███████▓▒░ ░▒▓██████▓▒░ ░▒▓██████▓▒░  
        // ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░      ░▒▓█▓▒░ 
        // ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░      ░▒▓█▓▒░ 
        // ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓███████▓▒░  
        //                                      
        // Name: Rexas Finance
        // Token: RXS
        // Website: https://rexas.com
        // Twitter/X: https://x.com/rexasfinance
        // Telegram: https://t.me/rexasfinance
        // 
        
        
        // SPDX-License-Identifier:MIT
        pragma solidity ^0.8.20;
        
        interface IERC20 {
            function totalSupply() external view returns (uint256);
        
            function balanceOf(address account) external view returns (uint256);
        
            function transfer(
                address recipient,
                uint256 amount
            ) external returns (bool);
        
            function allowance(
                address owner,
                address spender
            ) external view returns (uint256);
        
            function approve(address spender, uint256 amount) external returns (bool);
        
            function transferFrom(
                address sender,
                address recipient,
                uint256 amount
            ) external returns (bool);
        
            event Transfer(address indexed from, address indexed to, uint256 value);
        
            event Approval(
                address indexed owner,
                address indexed spender,
                uint256 value
            );
        }
        
        // Dex Factory contract interface
        interface IDexFactory {
            function createPair(
                address tokenA,
                address tokenB
            ) external returns (address pair);
        }
        
        // Dex Router contract interface
        interface IDexRouter {
            function factory() external pure returns (address);
        
            function WETH() external pure returns (address);
        
            function addLiquidityETH(
                address token,
                uint256 amountTokenDesired,
                uint256 amountTokenMin,
                uint256 amountETHMin,
                address to,
                uint256 deadline
            )
                external
                payable
                returns (uint256 amountToken, uint256 amountETH, uint256 liquidity);
        
            function swapExactTokensForETHSupportingFeeOnTransferTokens(
                uint256 amountIn,
                uint256 amountOutMin,
                address[] calldata path,
                address to,
                uint256 deadline
            ) external;
        }
        
        abstract contract Context {
            function _msgSender() internal view virtual returns (address payable) {
                return payable(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;
            }
        }
        
        contract Ownable is Context {
            address private _owner;
        
            event OwnershipTransferred(
                address indexed previousOwner,
                address indexed newOwner
            );
        
            constructor() {
                _owner = _msgSender();
                emit OwnershipTransferred(address(0), _owner);
            }
        
            function owner() public view returns (address) {
                return _owner;
            }
        
            modifier onlyOwner() {
                require(_owner == _msgSender(), "Ownable: caller is not the owner");
                _;
            }
        
            function renounceOwnership() public virtual onlyOwner {
                emit OwnershipTransferred(_owner, address(0));
                _owner = payable(address(0));
            }
        
            function transferOwnership(address newOwner) public virtual onlyOwner {
                require(
                    newOwner != address(0),
                    "Ownable: new owner is the zero address"
                );
                emit OwnershipTransferred(_owner, newOwner);
                _owner = newOwner;
            }
        }
        
        contract REXAS_FINANCE is Context, IERC20, Ownable {
            using SafeMath for uint256;
        
            mapping(address => uint256) private _balances;
            mapping(address => mapping(address => uint256)) private _allowances;
            mapping(address => bool) public whitelist;
        
            string private _name = "Rexas Finance";
            string private _symbol = "RXS";
            uint8 private _decimals = 18;
            uint256 private _totalSupply = 1_000_000_000 * 1e18;
        
            bool public trading; // once enable can't be disable afterwards
        
        
            constructor() {
                whitelist[msg.sender] = true;
                _balances[owner()] = _totalSupply;
                
                emit Transfer(address(0), owner(), _totalSupply);
            }
        
            //to receive ETH from dexRouter when swapping
            receive() external payable {}
        
            function name() public view returns (string memory) {
                return _name;
            }
        
            function symbol() public view returns (string memory) {
                return _symbol;
            }
        
            function decimals() public view returns (uint8) {
                return _decimals;
            }
        
            function totalSupply() public view override returns (uint256) {
                return _totalSupply;
            }
        
            function balanceOf(address account) public view override returns (uint256) {
                return _balances[account];
            }
        
            function transfer(
                address recipient,
                uint256 amount
            ) public override returns (bool) {
                _transfer(_msgSender(), recipient, amount);
                return true;
            }
        
            function allowance(
                address owner,
                address spender
            ) public view override returns (uint256) {
                return _allowances[owner][spender];
            }
        
            function approve(
                address spender,
                uint256 amount
            ) public override returns (bool) {
                _approve(_msgSender(), spender, amount);
                return true;
            }
        
            function transferFrom(
                address sender,
                address recipient,
                uint256 amount
            ) public override returns (bool) {
                _transfer(sender, recipient, amount);
                _approve(
                    sender,
                    _msgSender(),
                    _allowances[sender][_msgSender()].sub(
                        amount,
                        "Rexas Finance: Transfer amount exceeds allowance"
                    )
                );
                return true;
            }
        
            function increaseAllowance(
                address spender,
                uint256 addedValue
            ) public virtual returns (bool) {
                _approve(
                    _msgSender(),
                    spender,
                    _allowances[_msgSender()][spender].add(addedValue)
                );
                return true;
            }
        
            function decreaseAllowance(
                address spender,
                uint256 subtractedValue
            ) public virtual returns (bool) {
                _approve(
                    _msgSender(),
                    spender,
                    _allowances[_msgSender()][spender].sub(
                        subtractedValue,
                        "Rexas Finance: Decreased allowance or below zero"
                    )
                );
                return true;
            }
        
            function removeStuckEth(address _receiver) public onlyOwner {
                payable(_receiver).transfer(address(this).balance);
            }
        
            function removeStuckToken(address _token, address _receiver, uint256 _amount) public onlyOwner {
                IERC20(_token).transfer(_receiver, _amount);
            }
        
            function enableTrading() external onlyOwner {
                require(!trading, "Rexas Finance: Already enabled");
                trading = true;
            }
        
            function setWhitelist(address _user, bool _exmpt) external onlyOwner{
                whitelist[_user] = _exmpt;
            }
        
            function _approve(address owner, address spender, uint256 amount) private {
                require(owner != address(0), "Rexas Finance: Approve from the zero address");
                require(spender != address(0), "Rexas Finance: Approve to the zero address");
        
                _allowances[owner][spender] = amount;
                emit Approval(owner, spender, amount);
            }
        
            function _transfer(address from, address to, uint256 amount) private {
                require(from != address(0), "Rexas Finance: Transfer from the zero address");
                require(to != address(0), "Rexas Finance: Transfer to the zero address");
                require(amount > 0, "Rexas Finance: Amount must be greater than zero");
        
                if (!whitelist[from] && !whitelist[to]) {
                    // trading disable till launch
                    require(trading,"Rexas Finance: Trading is disable");
                }
        
                _balances[from] = _balances[from].sub(
                    amount,
                    "Rexas Finance: Insufficient balance"
                );
                _balances[to] = _balances[to].add(amount);
        
                emit Transfer(from, to, amount);
            }
        
        }
        
        library SafeMath {
            function add(uint256 a, uint256 b) internal pure returns (uint256) {
                uint256 c = a + b;
                require(c >= a, "SafeMath: addition overflow");
        
                return c;
            }
        
            function sub(uint256 a, uint256 b) internal pure returns (uint256) {
                return sub(a, b, "SafeMath: subtraction overflow");
            }
        
            function sub(
                uint256 a,
                uint256 b,
                string memory errorMessage
            ) internal pure returns (uint256) {
                require(b <= a, errorMessage);
                uint256 c = a - b;
        
                return c;
            }
        
            function mul(uint256 a, uint256 b) internal pure returns (uint256) {
                // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
                // benefit is lost if 'b' is also tested.
                // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
                if (a == 0) {
                    return 0;
                }
        
                uint256 c = a * b;
                require(c / a == b, "SafeMath: multiplication overflow");
        
                return c;
            }
        
            function div(uint256 a, uint256 b) internal pure returns (uint256) {
                return div(a, b, "SafeMath: division by zero");
            }
        
            function div(
                uint256 a,
                uint256 b,
                string memory errorMessage
            ) internal pure returns (uint256) {
                require(b > 0, errorMessage);
                uint256 c = a / b;
                // assert(a == b * c + a % b); // There is no case in which this doesn't hold
        
                return c;
            }
        
            function mod(uint256 a, uint256 b) internal pure returns (uint256) {
                return mod(a, b, "SafeMath: modulo by zero");
            }
        
            function mod(
                uint256 a,
                uint256 b,
                string memory errorMessage
            ) internal pure returns (uint256) {
                require(b != 0, errorMessage);
                return a % b;
            }
        }

        File 3 of 3: EACAggregatorProxy
        pragma solidity 0.6.6;
        
        
        /**
         * @title The Owned contract
         * @notice A contract with helpers for basic contract ownership.
         */
        contract Owned {
        
          address payable public owner;
          address private pendingOwner;
        
          event OwnershipTransferRequested(
            address indexed from,
            address indexed to
          );
          event OwnershipTransferred(
            address indexed from,
            address indexed to
          );
        
          constructor() public {
            owner = msg.sender;
          }
        
          /**
           * @dev Allows an owner to begin transferring ownership to a new address,
           * pending.
           */
          function transferOwnership(address _to)
            external
            onlyOwner()
          {
            pendingOwner = _to;
        
            emit OwnershipTransferRequested(owner, _to);
          }
        
          /**
           * @dev Allows an ownership transfer to be completed by the recipient.
           */
          function acceptOwnership()
            external
          {
            require(msg.sender == pendingOwner, "Must be proposed owner");
        
            address oldOwner = owner;
            owner = msg.sender;
            pendingOwner = address(0);
        
            emit OwnershipTransferred(oldOwner, msg.sender);
          }
        
          /**
           * @dev Reverts if called by anyone other than the contract owner.
           */
          modifier onlyOwner() {
            require(msg.sender == owner, "Only callable by owner");
            _;
          }
        
        }
        
        interface AggregatorInterface {
          function latestAnswer() external view returns (int256);
          function latestTimestamp() external view returns (uint256);
          function latestRound() external view returns (uint256);
          function getAnswer(uint256 roundId) external view returns (int256);
          function getTimestamp(uint256 roundId) external view returns (uint256);
        
          event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt);
          event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt);
        }
        
        interface AggregatorV3Interface {
        
          function decimals() external view returns (uint8);
          function description() external view returns (string memory);
          function version() external view returns (uint256);
        
          // getRoundData and latestRoundData should both raise "No data present"
          // if they do not have data to report, instead of returning unset values
          // which could be misinterpreted as actual reported values.
          function getRoundData(uint80 _roundId)
            external
            view
            returns (
              uint80 roundId,
              int256 answer,
              uint256 startedAt,
              uint256 updatedAt,
              uint80 answeredInRound
            );
          function latestRoundData()
            external
            view
            returns (
              uint80 roundId,
              int256 answer,
              uint256 startedAt,
              uint256 updatedAt,
              uint80 answeredInRound
            );
        
        }
        
        interface AggregatorV2V3Interface is AggregatorInterface, AggregatorV3Interface
        {
        }
        
        /**
         * @title A trusted proxy for updating where current answers are read from
         * @notice This contract provides a consistent address for the
         * CurrentAnwerInterface but delegates where it reads from to the owner, who is
         * trusted to update it.
         */
        contract AggregatorProxy is AggregatorV2V3Interface, Owned {
        
          struct Phase {
            uint16 id;
            AggregatorV2V3Interface aggregator;
          }
          Phase private currentPhase;
          AggregatorV2V3Interface public proposedAggregator;
          mapping(uint16 => AggregatorV2V3Interface) public phaseAggregators;
        
          uint256 constant private PHASE_OFFSET = 64;
          uint256 constant private PHASE_SIZE = 16;
          uint256 constant private MAX_ID = 2**(PHASE_OFFSET+PHASE_SIZE) - 1;
        
          constructor(address _aggregator) public Owned() {
            setAggregator(_aggregator);
          }
        
          /**
           * @notice Reads the current answer from aggregator delegated to.
           *
           * @dev #[deprecated] Use latestRoundData instead. This does not error if no
           * answer has been reached, it will simply return 0. Either wait to point to
           * an already answered Aggregator or use the recommended latestRoundData
           * instead which includes better verification information.
           */
          function latestAnswer()
            public
            view
            virtual
            override
            returns (int256 answer)
          {
            return currentPhase.aggregator.latestAnswer();
          }
        
          /**
           * @notice Reads the last updated height from aggregator delegated to.
           *
           * @dev #[deprecated] Use latestRoundData instead. This does not error if no
           * answer has been reached, it will simply return 0. Either wait to point to
           * an already answered Aggregator or use the recommended latestRoundData
           * instead which includes better verification information.
           */
          function latestTimestamp()
            public
            view
            virtual
            override
            returns (uint256 updatedAt)
          {
            return currentPhase.aggregator.latestTimestamp();
          }
        
          /**
           * @notice get past rounds answers
           * @param _roundId the answer number to retrieve the answer for
           *
           * @dev #[deprecated] Use getRoundData instead. This does not error if no
           * answer has been reached, it will simply return 0. Either wait to point to
           * an already answered Aggregator or use the recommended getRoundData
           * instead which includes better verification information.
           */
          function getAnswer(uint256 _roundId)
            public
            view
            virtual
            override
            returns (int256 answer)
          {
            if (_roundId > MAX_ID) return 0;
        
            (uint16 phaseId, uint64 aggregatorRoundId) = parseIds(_roundId);
            AggregatorV2V3Interface aggregator = phaseAggregators[phaseId];
            if (address(aggregator) == address(0)) return 0;
        
            return aggregator.getAnswer(aggregatorRoundId);
          }
        
          /**
           * @notice get block timestamp when an answer was last updated
           * @param _roundId the answer number to retrieve the updated timestamp for
           *
           * @dev #[deprecated] Use getRoundData instead. This does not error if no
           * answer has been reached, it will simply return 0. Either wait to point to
           * an already answered Aggregator or use the recommended getRoundData
           * instead which includes better verification information.
           */
          function getTimestamp(uint256 _roundId)
            public
            view
            virtual
            override
            returns (uint256 updatedAt)
          {
            if (_roundId > MAX_ID) return 0;
        
            (uint16 phaseId, uint64 aggregatorRoundId) = parseIds(_roundId);
            AggregatorV2V3Interface aggregator = phaseAggregators[phaseId];
            if (address(aggregator) == address(0)) return 0;
        
            return aggregator.getTimestamp(aggregatorRoundId);
          }
        
          /**
           * @notice get the latest completed round where the answer was updated. This
           * ID includes the proxy's phase, to make sure round IDs increase even when
           * switching to a newly deployed aggregator.
           *
           * @dev #[deprecated] Use latestRoundData instead. This does not error if no
           * answer has been reached, it will simply return 0. Either wait to point to
           * an already answered Aggregator or use the recommended latestRoundData
           * instead which includes better verification information.
           */
          function latestRound()
            public
            view
            virtual
            override
            returns (uint256 roundId)
          {
            Phase memory phase = currentPhase; // cache storage reads
            return addPhase(phase.id, uint64(phase.aggregator.latestRound()));
          }
        
          /**
           * @notice get data about a round. Consumers are encouraged to check
           * that they're receiving fresh data by inspecting the updatedAt and
           * answeredInRound return values.
           * Note that different underlying implementations of AggregatorV3Interface
           * have slightly different semantics for some of the return values. Consumers
           * should determine what implementations they expect to receive
           * data from and validate that they can properly handle return data from all
           * of them.
           * @param _roundId the requested round ID as presented through the proxy, this
           * is made up of the aggregator's round ID with the phase ID encoded in the
           * two highest order bytes
           * @return roundId is the round ID from the aggregator for which the data was
           * retrieved combined with an phase to ensure that round IDs get larger as
           * time moves forward.
           * @return answer is the answer for the given round
           * @return startedAt is the timestamp when the round was started.
           * (Only some AggregatorV3Interface implementations return meaningful values)
           * @return updatedAt is the timestamp when the round last was updated (i.e.
           * answer was last computed)
           * @return answeredInRound is the round ID of the round in which the answer
           * was computed.
           * (Only some AggregatorV3Interface implementations return meaningful values)
           * @dev Note that answer and updatedAt may change between queries.
           */
          function getRoundData(uint80 _roundId)
            public
            view
            virtual
            override
            returns (
              uint80 roundId,
              int256 answer,
              uint256 startedAt,
              uint256 updatedAt,
              uint80 answeredInRound
            )
          {
            (uint16 phaseId, uint64 aggregatorRoundId) = parseIds(_roundId);
        
            (
              uint80 roundId,
              int256 answer,
              uint256 startedAt,
              uint256 updatedAt,
              uint80 ansIn
            ) = phaseAggregators[phaseId].getRoundData(aggregatorRoundId);
        
            return addPhaseIds(roundId, answer, startedAt, updatedAt, ansIn, phaseId);
          }
        
          /**
           * @notice get data about the latest round. Consumers are encouraged to check
           * that they're receiving fresh data by inspecting the updatedAt and
           * answeredInRound return values.
           * Note that different underlying implementations of AggregatorV3Interface
           * have slightly different semantics for some of the return values. Consumers
           * should determine what implementations they expect to receive
           * data from and validate that they can properly handle return data from all
           * of them.
           * @return roundId is the round ID from the aggregator for which the data was
           * retrieved combined with an phase to ensure that round IDs get larger as
           * time moves forward.
           * @return answer is the answer for the given round
           * @return startedAt is the timestamp when the round was started.
           * (Only some AggregatorV3Interface implementations return meaningful values)
           * @return updatedAt is the timestamp when the round last was updated (i.e.
           * answer was last computed)
           * @return answeredInRound is the round ID of the round in which the answer
           * was computed.
           * (Only some AggregatorV3Interface implementations return meaningful values)
           * @dev Note that answer and updatedAt may change between queries.
           */
          function latestRoundData()
            public
            view
            virtual
            override
            returns (
              uint80 roundId,
              int256 answer,
              uint256 startedAt,
              uint256 updatedAt,
              uint80 answeredInRound
            )
          {
            Phase memory current = currentPhase; // cache storage reads
        
            (
              uint80 roundId,
              int256 answer,
              uint256 startedAt,
              uint256 updatedAt,
              uint80 ansIn
            ) = current.aggregator.latestRoundData();
        
            return addPhaseIds(roundId, answer, startedAt, updatedAt, ansIn, current.id);
          }
        
          /**
           * @notice Used if an aggregator contract has been proposed.
           * @param _roundId the round ID to retrieve the round data for
           * @return roundId is the round ID for which data was retrieved
           * @return answer is the answer for the given round
           * @return startedAt is the timestamp when the round was started.
           * (Only some AggregatorV3Interface implementations return meaningful values)
           * @return updatedAt is the timestamp when the round last was updated (i.e.
           * answer was last computed)
           * @return answeredInRound is the round ID of the round in which the answer
           * was computed.
          */
          function proposedGetRoundData(uint80 _roundId)
            public
            view
            virtual
            hasProposal()
            returns (
              uint80 roundId,
              int256 answer,
              uint256 startedAt,
              uint256 updatedAt,
              uint80 answeredInRound
            )
          {
            return proposedAggregator.getRoundData(_roundId);
          }
        
          /**
           * @notice Used if an aggregator contract has been proposed.
           * @return roundId is the round ID for which data was retrieved
           * @return answer is the answer for the given round
           * @return startedAt is the timestamp when the round was started.
           * (Only some AggregatorV3Interface implementations return meaningful values)
           * @return updatedAt is the timestamp when the round last was updated (i.e.
           * answer was last computed)
           * @return answeredInRound is the round ID of the round in which the answer
           * was computed.
          */
          function proposedLatestRoundData()
            public
            view
            virtual
            hasProposal()
            returns (
              uint80 roundId,
              int256 answer,
              uint256 startedAt,
              uint256 updatedAt,
              uint80 answeredInRound
            )
          {
            return proposedAggregator.latestRoundData();
          }
        
          /**
           * @notice returns the current phase's aggregator address.
           */
          function aggregator()
            external
            view
            returns (address)
          {
            return address(currentPhase.aggregator);
          }
        
          /**
           * @notice returns the current phase's ID.
           */
          function phaseId()
            external
            view
            returns (uint16)
          {
            return currentPhase.id;
          }
        
          /**
           * @notice represents the number of decimals the aggregator responses represent.
           */
          function decimals()
            external
            view
            override
            returns (uint8)
          {
            return currentPhase.aggregator.decimals();
          }
        
          /**
           * @notice the version number representing the type of aggregator the proxy
           * points to.
           */
          function version()
            external
            view
            override
            returns (uint256)
          {
            return currentPhase.aggregator.version();
          }
        
          /**
           * @notice returns the description of the aggregator the proxy points to.
           */
          function description()
            external
            view
            override
            returns (string memory)
          {
            return currentPhase.aggregator.description();
          }
        
          /**
           * @notice Allows the owner to propose a new address for the aggregator
           * @param _aggregator The new address for the aggregator contract
           */
          function proposeAggregator(address _aggregator)
            external
            onlyOwner()
          {
            proposedAggregator = AggregatorV2V3Interface(_aggregator);
          }
        
          /**
           * @notice Allows the owner to confirm and change the address
           * to the proposed aggregator
           * @dev Reverts if the given address doesn't match what was previously
           * proposed
           * @param _aggregator The new address for the aggregator contract
           */
          function confirmAggregator(address _aggregator)
            external
            onlyOwner()
          {
            require(_aggregator == address(proposedAggregator), "Invalid proposed aggregator");
            delete proposedAggregator;
            setAggregator(_aggregator);
          }
        
        
          /*
           * Internal
           */
        
          function setAggregator(address _aggregator)
            internal
          {
            uint16 id = currentPhase.id + 1;
            currentPhase = Phase(id, AggregatorV2V3Interface(_aggregator));
            phaseAggregators[id] = AggregatorV2V3Interface(_aggregator);
          }
        
          function addPhase(
            uint16 _phase,
            uint64 _originalId
          )
            internal
            view
            returns (uint80)
          {
            return uint80(uint256(_phase) << PHASE_OFFSET | _originalId);
          }
        
          function parseIds(
            uint256 _roundId
          )
            internal
            view
            returns (uint16, uint64)
          {
            uint16 phaseId = uint16(_roundId >> PHASE_OFFSET);
            uint64 aggregatorRoundId = uint64(_roundId);
        
            return (phaseId, aggregatorRoundId);
          }
        
          function addPhaseIds(
              uint80 roundId,
              int256 answer,
              uint256 startedAt,
              uint256 updatedAt,
              uint80 answeredInRound,
              uint16 phaseId
          )
            internal
            view
            returns (uint80, int256, uint256, uint256, uint80)
          {
            return (
              addPhase(phaseId, uint64(roundId)),
              answer,
              startedAt,
              updatedAt,
              addPhase(phaseId, uint64(answeredInRound))
            );
          }
        
          /*
           * Modifiers
           */
        
          modifier hasProposal() {
            require(address(proposedAggregator) != address(0), "No proposed aggregator present");
            _;
          }
        
        }
        
        interface AccessControllerInterface {
          function hasAccess(address user, bytes calldata data) external view returns (bool);
        }
        
        /**
         * @title External Access Controlled Aggregator Proxy
         * @notice A trusted proxy for updating where current answers are read from
         * @notice This contract provides a consistent address for the
         * Aggregator and AggregatorV3Interface but delegates where it reads from to the owner, who is
         * trusted to update it.
         * @notice Only access enabled addresses are allowed to access getters for
         * aggregated answers and round information.
         */
        contract EACAggregatorProxy is AggregatorProxy {
        
          AccessControllerInterface public accessController;
        
          constructor(
            address _aggregator,
            address _accessController
          )
            public
            AggregatorProxy(_aggregator)
          {
            setController(_accessController);
          }
        
          /**
           * @notice Allows the owner to update the accessController contract address.
           * @param _accessController The new address for the accessController contract
           */
          function setController(address _accessController)
            public
            onlyOwner()
          {
            accessController = AccessControllerInterface(_accessController);
          }
        
          /**
           * @notice Reads the current answer from aggregator delegated to.
           * @dev overridden function to add the checkAccess() modifier
           *
           * @dev #[deprecated] Use latestRoundData instead. This does not error if no
           * answer has been reached, it will simply return 0. Either wait to point to
           * an already answered Aggregator or use the recommended latestRoundData
           * instead which includes better verification information.
           */
          function latestAnswer()
            public
            view
            override
            checkAccess()
            returns (int256)
          {
            return super.latestAnswer();
          }
        
          /**
           * @notice get the latest completed round where the answer was updated. This
           * ID includes the proxy's phase, to make sure round IDs increase even when
           * switching to a newly deployed aggregator.
           *
           * @dev #[deprecated] Use latestRoundData instead. This does not error if no
           * answer has been reached, it will simply return 0. Either wait to point to
           * an already answered Aggregator or use the recommended latestRoundData
           * instead which includes better verification information.
           */
          function latestTimestamp()
            public
            view
            override
            checkAccess()
            returns (uint256)
          {
            return super.latestTimestamp();
          }
        
          /**
           * @notice get past rounds answers
           * @param _roundId the answer number to retrieve the answer for
           * @dev overridden function to add the checkAccess() modifier
           *
           * @dev #[deprecated] Use getRoundData instead. This does not error if no
           * answer has been reached, it will simply return 0. Either wait to point to
           * an already answered Aggregator or use the recommended getRoundData
           * instead which includes better verification information.
           */
          function getAnswer(uint256 _roundId)
            public
            view
            override
            checkAccess()
            returns (int256)
          {
            return super.getAnswer(_roundId);
          }
        
          /**
           * @notice get block timestamp when an answer was last updated
           * @param _roundId the answer number to retrieve the updated timestamp for
           * @dev overridden function to add the checkAccess() modifier
           *
           * @dev #[deprecated] Use getRoundData instead. This does not error if no
           * answer has been reached, it will simply return 0. Either wait to point to
           * an already answered Aggregator or use the recommended getRoundData
           * instead which includes better verification information.
           */
          function getTimestamp(uint256 _roundId)
            public
            view
            override
            checkAccess()
            returns (uint256)
          {
            return super.getTimestamp(_roundId);
          }
        
          /**
           * @notice get the latest completed round where the answer was updated
           * @dev overridden function to add the checkAccess() modifier
           *
           * @dev #[deprecated] Use latestRoundData instead. This does not error if no
           * answer has been reached, it will simply return 0. Either wait to point to
           * an already answered Aggregator or use the recommended latestRoundData
           * instead which includes better verification information.
           */
          function latestRound()
            public
            view
            override
            checkAccess()
            returns (uint256)
          {
            return super.latestRound();
          }
        
          /**
           * @notice get data about a round. Consumers are encouraged to check
           * that they're receiving fresh data by inspecting the updatedAt and
           * answeredInRound return values.
           * Note that different underlying implementations of AggregatorV3Interface
           * have slightly different semantics for some of the return values. Consumers
           * should determine what implementations they expect to receive
           * data from and validate that they can properly handle return data from all
           * of them.
           * @param _roundId the round ID to retrieve the round data for
           * @return roundId is the round ID from the aggregator for which the data was
           * retrieved combined with a phase to ensure that round IDs get larger as
           * time moves forward.
           * @return answer is the answer for the given round
           * @return startedAt is the timestamp when the round was started.
           * (Only some AggregatorV3Interface implementations return meaningful values)
           * @return updatedAt is the timestamp when the round last was updated (i.e.
           * answer was last computed)
           * @return answeredInRound is the round ID of the round in which the answer
           * was computed.
           * (Only some AggregatorV3Interface implementations return meaningful values)
           * @dev Note that answer and updatedAt may change between queries.
           */
          function getRoundData(uint80 _roundId)
            public
            view
            checkAccess()
            override
            returns (
              uint80 roundId,
              int256 answer,
              uint256 startedAt,
              uint256 updatedAt,
              uint80 answeredInRound
            )
          {
            return super.getRoundData(_roundId);
          }
        
          /**
           * @notice get data about the latest round. Consumers are encouraged to check
           * that they're receiving fresh data by inspecting the updatedAt and
           * answeredInRound return values.
           * Note that different underlying implementations of AggregatorV3Interface
           * have slightly different semantics for some of the return values. Consumers
           * should determine what implementations they expect to receive
           * data from and validate that they can properly handle return data from all
           * of them.
           * @return roundId is the round ID from the aggregator for which the data was
           * retrieved combined with a phase to ensure that round IDs get larger as
           * time moves forward.
           * @return answer is the answer for the given round
           * @return startedAt is the timestamp when the round was started.
           * (Only some AggregatorV3Interface implementations return meaningful values)
           * @return updatedAt is the timestamp when the round last was updated (i.e.
           * answer was last computed)
           * @return answeredInRound is the round ID of the round in which the answer
           * was computed.
           * (Only some AggregatorV3Interface implementations return meaningful values)
           * @dev Note that answer and updatedAt may change between queries.
           */
          function latestRoundData()
            public
            view
            checkAccess()
            override
            returns (
              uint80 roundId,
              int256 answer,
              uint256 startedAt,
              uint256 updatedAt,
              uint80 answeredInRound
            )
          {
            return super.latestRoundData();
          }
        
          /**
           * @notice Used if an aggregator contract has been proposed.
           * @param _roundId the round ID to retrieve the round data for
           * @return roundId is the round ID for which data was retrieved
           * @return answer is the answer for the given round
           * @return startedAt is the timestamp when the round was started.
           * (Only some AggregatorV3Interface implementations return meaningful values)
           * @return updatedAt is the timestamp when the round last was updated (i.e.
           * answer was last computed)
           * @return answeredInRound is the round ID of the round in which the answer
           * was computed.
          */
          function proposedGetRoundData(uint80 _roundId)
            public
            view
            checkAccess()
            hasProposal()
            override
            returns (
              uint80 roundId,
              int256 answer,
              uint256 startedAt,
              uint256 updatedAt,
              uint80 answeredInRound
            )
          {
            return super.proposedGetRoundData(_roundId);
          }
        
          /**
           * @notice Used if an aggregator contract has been proposed.
           * @return roundId is the round ID for which data was retrieved
           * @return answer is the answer for the given round
           * @return startedAt is the timestamp when the round was started.
           * (Only some AggregatorV3Interface implementations return meaningful values)
           * @return updatedAt is the timestamp when the round last was updated (i.e.
           * answer was last computed)
           * @return answeredInRound is the round ID of the round in which the answer
           * was computed.
          */
          function proposedLatestRoundData()
            public
            view
            checkAccess()
            hasProposal()
            override
            returns (
              uint80 roundId,
              int256 answer,
              uint256 startedAt,
              uint256 updatedAt,
              uint80 answeredInRound
            )
          {
            return super.proposedLatestRoundData();
          }
        
          /**
           * @dev reverts if the caller does not have access by the accessController
           * contract or is the contract itself.
           */
          modifier checkAccess() {
            AccessControllerInterface ac = accessController;
            require(address(ac) == address(0) || ac.hasAccess(msg.sender, msg.data), "No access");
            _;
          }
        }