AFTExchange Contract

Here you can find all information about the AFT Exchange contract.

AFTExchange.sol

This contract is deployed on Polygon at the following address:

0x4203826ebC178ef3080deaEaC11C56b22FdEb874

This contract is responsible for the exchange between NFM and AFT. The AFT will also only be tradeable on this exchange, since its algorithm does not allow normal trading.

This establishes a fixed exchange rate that always remains the same. 10,000 NFM = 1 AFT

Through this contract, the exchange of NFM in AFT is possible and guaranteed from AFT to NFM. The DaoReserveERC20 was specially whitelisted to support the AFT algorithm.

AFTExchange.sol
/**
 *Submitted for verification at polygonscan.com on 2022-11-15
 */

//SPDX-License-Identifier:MIT
pragma solidity ^0.8.13;

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// INTERFACES
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// IAFTCONTROLLER
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
interface IAFTController {
    function _checkWLSC(address root, address client)
        external
        view
        returns (bool);

    function _getAFT() external view returns (address);

    function _getDaoReserveERC20() external view returns (address);
}

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// INFMCONTROLLER
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
interface INFMController {
    function _getNFM() external view returns (address);
}

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// IDAORESERVEERC20
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
interface IDAOReserveERC20 {
    function withdraw(
        address Coin,
        address To,
        uint256 amount,
        bool percent
    ) external returns (bool);
}

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// IAFT
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
interface IAFT {
    function balanceOf(address account) external view returns (uint256);

    function _returnTokenReference(address account)
        external
        view
        returns (uint256, uint256);

    function totalSupply() external view returns (uint256);

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);

    function _mint(address to) external returns (bool);

    function allowance(address owner, address spender)
        external
        view
        returns (uint256);
}

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// INFM
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
interface INFM {
    function balanceOf(address account) external view returns (uint256);

    function allowance(address owner, address spender)
        external
        view
        returns (uint256);

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
/// @title AFTExchange.sol
/// @author Fernando Viktor Seidl E-mail: [email protected]
/// @notice This contract is responsible for the exchange of NFM for AFT. The exchange is and will only be possible via this exchange. This ensures a
///         fixed exchange rate between AFT and NFM, which is always 10000NFM = 1 AFT.
/// @dev    Since the AFT has an internal algorithm that prohibits having more than 1 AFT on one address, the DaoReserve
///         contract was whitelisted for the exchange contract. Only this address has the right to hold more than 1 AFT.
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
contract AFTExchange {
    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    //EXCHANGE STRUCT
    /*
    Contains all Exchanges Information
     */
    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    struct Exchanges {
        address _Applier;
        uint256 _Type;
        uint256 _AFTid;
        uint256 _TimeAction;
    }
    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    //VARIABLES
    /*
    @ exchanges = Exchange Counter
    @ allExchanges = Array with all Exchanges
     */
    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    uint256 private _exchangesCount = 0;
    Exchanges[] private allExchanges;
    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    /*
    CONTROLLER
    OWNER = MSG.SENDER ownership will be handed over to dao
     */
    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    address private _Owner;
    address private _SAFT;
    address private _SNFM;
    uint256 _locked = 0;
    IAFTController private _AFTController;
    INFMController private _NFMController;
    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    /*
    MAPPINGS
    ExchangeID(uint256 => Exchanges)          Exchange Counter => Exchange Struct.
    */
    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    mapping(uint256 => Exchanges) private ExchangeID;
    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    /* 
    MODIFIER
    reentrancyGuard       => Safety agains Reentrancy attacks.
     */
    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    modifier reentrancyGuard() {
        require(_locked == 0);
        _locked = 1;
        _;
        _locked = 0;
    }

    constructor(address AFTControll, address NFMControll) {
        _Owner = msg.sender;
        IAFTController _AFTCo = IAFTController(address(AFTControll));
        _AFTController = _AFTCo;
        INFMController _NFMCo = INFMController(address(NFMControll));
        _NFMController = _NFMCo;
        _SAFT = AFTControll;
        _SNFM = NFMControll;
    }

    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    /*
    @ storeEX(address Aktion,uint256 Type,uint256 AFTId,address TX)
    Store Exchange Information
     */
    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    function storeEX(
        address Aktion,
        uint256 Type, //1 is buy 2 is sold
        uint256 AFTId
    ) internal returns (bool) {
        require(msg.sender != address(0), "0A");
        
        ExchangeID[_exchangesCount] = Exchanges(
            Aktion,
            Type,
            AFTId,
            block.timestamp
        );
        allExchanges.push(ExchangeID[_exchangesCount]);
        _exchangesCount++;
        return true;
    }

    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    /*
    @ returnallEX( )
    Return all Exchanges made
     */
    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    function returnallEX() public view returns (Exchanges[] memory) {
        return allExchanges;
    }

    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    /*
    @ returnEXOnID(uint256 ExId)
    Return Exchange on ID
     */
    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    function returnEXOnID(uint256 ExId) public view returns (Exchanges memory) {
        return ExchangeID[ExId];
    }

    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    /*
    @ exchangeMyNFM()
    Exchange NFM against AFT. The user must have previously given the contract an allowance of 10000 NFM.
     */
    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    function exchangeMyNFM() public reentrancyGuard returns (bool) {
        require(
            INFM(address(_NFMController._getNFM())).allowance(
                msg.sender,
                address(this)
            ) >= 10000 * 10**18,
            "<A"
        );
        require(
            IAFT(address(_AFTController._getAFT())).totalSupply() < 1000000 ||
                IAFT(address(_AFTController._getAFT())).balanceOf(
                    address(_AFTController._getDaoReserveERC20())
                ) >
                0,
            "NE"
        );
        if (
            IAFT(address(_AFTController._getAFT())).balanceOf(
                address(_AFTController._getDaoReserveERC20())
            ) > 0
        ) {
            //no new issue, just exchange existing aft agains nfm
            if (
                INFM(address(_NFMController._getNFM())).transferFrom(
                    msg.sender,
                    address(_AFTController._getDaoReserveERC20()),
                    10000 * 10**18
                ) == true
            ) {
                require(
                    IDAOReserveERC20(
                        address(_AFTController._getDaoReserveERC20())
                    ).withdraw(
                            address(_AFTController._getAFT()),
                            msg.sender,
                            1,
                            false
                        ) == true,
                    "RD"
                );
                (, uint256 Tref) = IAFT(address(_AFTController._getAFT()))
                    ._returnTokenReference(msg.sender);
                require(storeEX(msg.sender, 1, Tref) == true, "NS");
            }
            return true;
        } else {
            //new issue
            if (
                INFM(address(_NFMController._getNFM())).transferFrom(
                    msg.sender,
                    address(_AFTController._getDaoReserveERC20()),
                    10000 * 10**18
                ) == true
            ) {
                require(
                    IAFT(address(_AFTController._getAFT()))._mint(msg.sender) ==
                        true,
                    "NT"
                );
                (, uint256 Tref) = IAFT(address(_AFTController._getAFT()))
                    ._returnTokenReference(msg.sender);
                require(storeEX(msg.sender, 1, Tref) == true, "NS");
            }
            return true;
        }
    }

    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    /*
    @ exchangeMyAFT()
    Exchange AFT against NFM. The user must have previously given the contract an allowance of 1 AFT.
     */
    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    function exchangeMyAFT() public reentrancyGuard returns (bool) {
        require(
            IAFT(address(_AFTController._getAFT())).allowance(
                msg.sender,
                address(this)
            ) > 0,
            "<A"
        );
        require(
            INFM(address(_NFMController._getNFM())).balanceOf(
                address(_AFTController._getDaoReserveERC20())
            ) >= 10000 * 10**18,
            "NE"
        );

        (, uint256 Tref) = IAFT(address(_AFTController._getAFT()))
            ._returnTokenReference(msg.sender);
        if (
            IAFT(address(_AFTController._getAFT())).transferFrom(
                msg.sender,
                address(_AFTController._getDaoReserveERC20()),
                1
            ) == true
        ) {
            require(
                IDAOReserveERC20(address(_AFTController._getDaoReserveERC20()))
                    .withdraw(
                        address(_NFMController._getNFM()),
                        msg.sender,
                        10000 * 10**18,
                        false
                    ) == true,
                "RD"
            );
            require(storeEX(msg.sender, 2, Tref) == true, "NS");
        }
        return true;
    }
}

Last updated