LockManager

This contract creates, tracks and handles the unlocking of the FNFTs.

Code

Read-Only Functions

fnftIdToLock

function fnftIdToLock(uint fnftId) public view override returns (IRevest.Lock memory) {
    return locks[fnftIdToLockId[fnftId]];
}

Returns the Lock object associated with the passed in fnftId.

getLock

function getLock(uint lockId) external view override returns (IRevest.Lock memory) {
    return locks[lockId];
}

Returns the lock object associated with the passed in lockId.

getSupply

function getSupply(uint fnftId) public view override returns (uint) {
    return supply[fnftId];
}

Gets the total supply of FNFTs within the given ID.

getLockMaturity

function getLockMaturity(uint fnftId) public view override returns (bool) {
    IRevest.Lock memory lock = locks[fnftIdToLockId[fnftId]];
    if (lock.lockType == IRevest.LockType.TimeLock) {
        return lock.unlocked || lock.timeLockExpiry < block.timestamp;
    }
    else if (lock.lockType == IRevest.LockType.ValueLock) {
        return lock.unlocked || getValueLockMaturity(fnftId);
    }
    else if (lock.lockType == IRevest.LockType.AddressLock) {
        return lock.unlocked || (lock.addressLock.supportsInterface(ADDRESS_LOCK_INTERFACE_ID) &&
                                    IAddressLock(lock.addressLock).isUnlockable(fnftId, fnftIdToLockId[fnftId]));
    }
    else {
        revert("E050");
    }
}

Helper function for getLockMaturity. Checks if a value lock is mature.

lockTypes

function lockTypes(uint tokenId) external view override returns (IRevest.LockType) {
    return fnftIdToLock(tokenId).lockType;
}
  • Gets the lock type for a given Id

  • fnftId - the FNFT id to check the lock type of

State-Changing Functions

pointFNFTToLock

function pointFNFTToLock(uint fnftId, uint lockId) external override onlyRevest {
    fnftIdToLockId[fnftId] = lockId;
}

Maps an FNFT id to a lock ID.

createLock

function createLock(uint fnftId, IRevest.LockParam memory lock) external override onlyRevest returns (uint) {
    // Extensive validation on creation
    require(lock.lockType != IRevest.LockType.DoesNotExist, "E058");
    IRevest.Lock storage newLock = locks[numLocks];
    newLock.lockType = lock.lockType;
    newLock.creationTime = block.timestamp;
    if(lock.lockType == IRevest.LockType.TimeLock) {
        require(lock.timeLockExpiry > block.timestamp, "E002");
        newLock.timeLockExpiry = lock.timeLockExpiry;
    }
    else if (lock.lockType == IRevest.LockType.ValueLock) {
        require(lock.valueLock.unlockValue > 0, "E003");
        require(lock.valueLock.compareTo != address(0) && lock.valueLock.asset != address(0), "E004");
        //Begin validation code to ensure this is actually keyed to a proper oracle
        IOracleDispatch oracle = IOracleDispatch(lock.valueLock.oracle);
        bool oraclePresent = oracle.getPairHasOracle(lock.valueLock.asset, lock.valueLock.compareTo);
        //If the oracle is not present, attempt to initialize it
        if(!oraclePresent && oracle.oracleNeedsInitialization(lock.valueLock.asset, lock.valueLock.compareTo)) {
            oraclePresent = oracle.initializeOracle(lock.valueLock.asset, lock.valueLock.compareTo);
        }
        require(oraclePresent, "E049");
        newLock.valueLock = lock.valueLock;
    }
    else if (lock.lockType == IRevest.LockType.AddressLock) {
        require(lock.addressLock != address(0), "E004");
        newLock.addressLock = lock.addressLock;
    }
    else {
        require(false, "Invalid type");
    }
    fnftIdToLockId[fnftId] = numLocks;
    numLocks += 1;
    return numLocks - 1;
}
  • Validates and creates a lock

  • fnftId - The ID to associate with this lock

  • Lock - The lock to validate and associate with the fnftId

  • RETURNS the lockId of the newly created lock

unlockFNFT

function unlockFNFT(uint fnftId, address sender) external override onlyRevestController returns (bool) {
    uint lockId = fnftIdToLockId[fnftId];
    IRevest.Lock storage lock = locks[lockId];
    IRevest.LockType typeLock = lock.lockType;
    if (typeLock == IRevest.LockType.TimeLock) {
        if(!lock.unlocked && lock.timeLockExpiry <= block.timestamp) {
            lock.unlocked = true;
            //Should refund some gas
            lock.timeLockExpiry = 0;
        }
    }
    else if (typeLock == IRevest.LockType.ValueLock) {
        bool unlockState;
        address oracleAdd =lock.valueLock.oracle;
        if(getLockMaturity(fnftId)) {
            unlockState = true;
        } else {
            IOracleDispatch oracle = IOracleDispatch(oracleAdd);
            unlockState = oracle.updateOracle(lock.valueLock.asset, lock.valueLock.compareTo) &&
                            getLockMaturity(fnftId);
        }
        if(unlockState && oracleAdd != address(0)) {
            //We only want to write this once
            lock.unlocked = true;
            //Refund some gas
            lock.valueLock.oracle = address(0);
            lock.valueLock.asset = address(0);
            lock.valueLock.compareTo = address(0);
            lock.valueLock.unlockValue = 0;
            lock.valueLock.unlockRisingEdge = false;
        }

    }
    else if (typeLock == IRevest.LockType.AddressLock) {
        address addLock = lock.addressLock;
        if (!lock.unlocked && (sender == addLock ||
                (addLock.supportsInterface(ADDRESS_LOCK_INTERFACE_ID) && IAddressLock(addLock).isUnlockable(fnftId, lockId)))
            ) {
            lock.unlocked = true;
            //Refund some gas
            lock.addressLock = address(0);
        }
    }
    return lock.unlocked;
}
  • Helper function for Revest.sol

  • Unlocks address or value locks after checking if they meet the conditions for unlock

  • lockId - The lockId to unlock

  • Sender - The address who has sent the request to Revest.sol

  • RETURNS - boolean of success at unlocking the lock

Interface

// SPDX-License-Identifier: GNU-GPL v3.0 or later

pragma solidity >=0.8.0;

import "./IRevest.sol";

/**
 * @title Mintable interface for Revest FNFTs
 * @dev ...
 */
interface ILockManager {

    function createLock(uint fnftId, IRevest.LockParam memory lock) external returns (uint);

    function getLock(uint lockId) external view returns (IRevest.Lock memory);

    function fnftIdToLockId(uint fnftId) external view returns (uint);

    function fnftIdToLock(uint fnftId) external view returns (IRevest.Lock memory);

    function pointFNFTToLock(uint fnftId, uint lockId) external;

    function lockTypes(uint tokenId) external view returns (IRevest.LockType);

    function unlockFNFT(uint fnftId, address sender) external returns (bool);

    function getLockMaturity(uint fnftId) external view returns (bool);
}

ABI

Last updated