# Crosspoly Techteam Weekly Report(Jul 19-Jul 23)



**1. Completed the settting of Fee Rate for the standard of trading**

![](https://512910346-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdZwKUzhB9gGNdw9JS7%2F-Mfvty05ClwMvhWXC9vk%2F-Mfvvl1dUZJpMqj8al5t%2F23%20-1%20fee.png?alt=media\&token=24560565-d937-4714-a13a-93be33531afd)

> /\* Copyright 2021 Crosspoly ZOO. SPDX-License-Identifier: Apache-2.0\*/ pragma solidity 0.6.9;pragma experimental ABIEncoderV2; import {InitializableOwnable} from “../lib/InitializableOwnable.sol”;import {IERC20} from “../intf/IERC20.sol”;import {SafeMath} from “../lib/SafeMath.sol”; interface ICrowdPooling { function \_QUOTE\_RESERVE\_() external view returns (uint256); function getShares(address user) external view returns (uint256);} interface IFee { function getUserFee(address user) external view returns (uint256);} interface IQuota { function getUserQuota(address user) external view returns (int);} interface IPool { function version() external pure returns (string memory); function \_LP\_FEE\_RATE\_() external view returns (uint256);} contract FeeRateDIP3Impl is InitializableOwnable { using SafeMath for uint256; // ============ Storage ============ uint256 public \_LP\_MT\_RATIO\_ = 25; struct CPPoolInfo { address quoteToken; int globalQuota; address feeAddr; address quotaAddr; } mapping(address => CPPoolInfo) cpPools; // ============ Ownable Functions ============ function addCpPoolInfo(address cpPool, address quoteToken, int globalQuota, address feeAddr, address quotaAddr) external onlyOwner { CPPoolInfo memory cpPoolInfo = CPPoolInfo({ quoteToken: quoteToken, feeAddr: feeAddr, quotaAddr: quotaAddr, globalQuota: globalQuota }); cpPools\[cpPool] = cpPoolInfo; } function setCpPoolInfo(address cpPool, address quoteToken, int globalQuota, address feeAddr, address quotaAddr) external onlyOwner { cpPools\[cpPool].quoteToken = quoteToken; cpPools\[cpPool].feeAddr = feeAddr; cpPools\[cpPool].quotaAddr = quotaAddr; cpPools\[cpPool].globalQuota = globalQuota; } function setLpMtRatio(uint256 newLpMtRatio) external onlyOwner { \_LP\_MT\_RATIO\_ = newLpMtRatio; } // ============ View Functions ============ function getFeeRate(address pool, address user) external view returns (uint256) { try IPool(pool).version() returns (string memory poolVersion) { bytes32 hashPoolVersion = keccak256(abi.encodePacked(poolVersion)); if(hashPoolVersion == keccak256(abi.encodePacked(“CP 1.0.0”))) { CPPoolInfo memory cpPoolInfo = cpPools\[pool]; address quoteToken = cpPoolInfo.quoteToken; if(quoteToken == address(0)) { return 0; }else { uint256 userInput = IERC20(quoteToken).balanceOf(pool).sub(ICrowdPooling(pool).\_QUOTE\_RESERVE\_()); uint256 userStake = ICrowdPooling(pool).getShares(user); address feeAddr = cpPoolInfo.feeAddr; address quotaAddr = cpPoolInfo.quotaAddr; int curQuota = cpPoolInfo.globalQuota; if(quotaAddr != address(0)) curQuota = IQuota(quotaAddr).getUserQuota(user); require(curQuota == -1 || (curQuota != -1 && int(userInput.add(userStake)) <= curQuota), “CrosspolyFeeImpl: EXCEED\_YOUR\_QUOTA”); if(feeAddr == address(0)) { return 0; } else { return IFee(feeAddr).getUserFee(user); } } } else if(hashPoolVersion == keccak256(abi.encodePacked(“DVM 1.0.2”)) || hashPoolVersion == keccak256(abi.encodePacked(“DSP 1.0.1”))) { uint256 lpFeeRate = IPool(pool).\_LP\_FEE\_RATE\_(); uint256 mtFeeRate = lpFeeRate.mul(\_LP\_MT\_RATIO\_).div(100); if(lpFeeRate.add(mtFeeRate) >= 10\*\*18) { return 0; } else { return mtFeeRate; } } else { return 0; } } catch (bytes memory) { return 0; } } function getCPInfoByUser(address pool, address user) external view returns (bool isHaveCap, int curQuota, uint256 userFee) { CPPoolInfo memory cpPoolInfo = cpPools\[pool]; if(cpPoolInfo.quoteToken == address(0)) { isHaveCap = false; curQuota = -1; userFee = 0; }else { address quotaAddr = cpPoolInfo.quotaAddr; curQuota = cpPoolInfo.globalQuota; if(quotaAddr != address(0)) curQuota = IQuota(quotaAddr).getUserQuota(user); if(curQuota == -1) { isHaveCap = false; }else { isHaveCap = true; uint256 userStake = ICrowdPooling(pool).getShares(user); curQuota = int(uint256(curQuota).sub(userStake)); } address feeAddr = cpPoolInfo.feeAddr; if(feeAddr == address(0)) { userFee = 0; } else { userFee = IFee(feeAddr).getUserFee(user)

**2. Completed the design of Private Pool for uesers to participate**

![](https://512910346-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdZwKUzhB9gGNdw9JS7%2F-Mfvty05ClwMvhWXC9vk%2F-MfvvwtwsWvM23XNe2ba%2F723-pkey.png?alt=media\&token=2f36888c-3be2-43e1-896d-340cdee9e242)

> Copyright 2020 Crosspoly ZOO. SPDX-License-Identifier: Apache-2.0\*/ pragma solidity 0.6.9;pragma experimental ABIEncoderV2; import {DPP} from “../DPP.sol”; /\*\* \* @title Crosspoly PrivatePool \* @author Crosspoly Breeder \* \* @notice Advanced CrosspolyPrivatePool \*/contract DPPAdvanced is DPP { function tuneParameters( uint256 newLpFeeRate, uint256 newI, uint256 newK, uint256 minBaseReserve, uint256 minQuoteReserve ) public preventReentrant onlyOwner returns (bool) { require( \_BASE\_RESERVE\_ >= minBaseReserve && \_QUOTE\_RESERVE\_ >= minQuoteReserve, “RESERVE\_AMOUNT\_IS\_NOT\_ENOUGH” ); require(newLpFeeRate <= 1e18, “LP\_FEE\_RATE\_OUT\_OF\_RANGE”); require(newK <= 1e18, “K\_OUT\_OF\_RANGE”); require(newI > 0 && newI <= 1e36, “I\_OUT\_OF\_RANGE”); \_LP\_FEE\_RATE\_ = uint64(newLpFeeRate); \_K\_ = uint64(newK); \_I\_ = uint128(newI); emit LpFeeRateChange(newLpFeeRate); return true; } function tunePrice( uint256 newI, uint256 minBaseReserve, uint256 minQuoteReserve ) public preventReentrant onlyOwner returns (bool) { require( \_BASE\_RESERVE\_ >= minBaseReserve && \_QUOTE\_RESERVE\_ >= minQuoteReserve, “RESERVE\_AMOUNT\_IS\_NOT\_ENOUGH” ); require(newI > 0 && newI <= 1e36, “I\_OUT\_OF\_RANGE”); \_I\_ = uint128(newI); return true; } // ============ Version Control ============ function version() override external pure returns (string memory) { return “DPP Advanced 1.0.0”;
