Router.sol

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

import "../interfaces/IVault.sol";
import "../interfaces/IPortfolio.sol";
import "../library/Bytes32Library.sol";
import "../library/StringLibrary.sol";
import "./OrderBooks.sol";
import "./TradePairs.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";

contract Router {   
    using SafeMath for uint256;
    using SafeERC20 for IERC20;
    using Address for address payable;
    using StringLibrary for string;
    using Bytes32Library for bytes32;

    address private vault;
    OrderBooks private orderBooks;
    IPortfolio private portfolio;
    TradePairs private tradePairs;

    constructor(address _orderBooks, address _portfolio, address _tradePairs, address _vault) {
        orderBooks = OrderBooks(_orderBooks);
        tradePairs = TradePairs(_tradePairs);
        portfolio = IPortfolio(_portfolio);
        vault = _vault;
    }

    function getQuoteAmount(bytes32 _tradePairId, uint256 _price, uint256 _quantity) private view returns (uint256) {
        uint8 baseDecimals = tradePairs.getDecimals(_tradePairId, true);
        return (_price * _quantity) / 10**baseDecimals;
    }
    
    function increasePosition(bytes32 _tradePairId, uint256 _amountIn, uint256 _leverage, bool _isLong) external {
        bytes32 baseSymbol = tradePairs.getSymbol(_tradePairId, true);
        if (_amountIn > 0) {
            IERC20Upgradeable baseAssetAddress = portfolio.getToken(baseSymbol);
            baseAssetAddress.transferFrom(address(msg.sender), vault, _amountIn);
        }
        bytes32 _buyBookId = string(abi.encodePacked(_tradePairId.bytes32ToString(), '-BUYBOOK')).stringToBytes32();
        bytes32 _sellBookId = string(abi.encodePacked(_tradePairId.bytes32ToString(), '-SELLBOOK')).stringToBytes32();
        uint256 price = _isLong ? orderBooks.first(_sellBookId) : orderBooks.last(_buyBookId);
        uint256 quoteAmount = getQuoteAmount(_tradePairId, price, _amountIn);
        uint256 _sizeDelta = quoteAmount * _leverage;
        _increasePosition(_tradePairId, _sizeDelta, _isLong);
    }

    function decreasePosition(bytes32 _tradePairId, uint256 _collateralDelta, uint256 _sizeDelta, bool _isLong, address _receiver) external {
        _decreasePosition(_tradePairId, _collateralDelta, _sizeDelta, _isLong, _receiver);
    }

    function _increasePosition(bytes32 _tradePairId, uint256 _sizeDelta, bool _isLong) private {
        IVault(vault).increasePosition(address(msg.sender), _tradePairId, _sizeDelta, _isLong);
    }

    function _decreasePosition(bytes32 _tradePairId, uint256 _collateralDelta, uint256 _sizeDelta, bool _isLong, address _receiver) private returns (uint256) {
        return IVault(vault).decreasePosition(address(msg.sender), _tradePairId, _collateralDelta, _sizeDelta, _isLong, _receiver);
    }
}

Last updated