编译器
0.8.19+commit.7dd6d404
文件 1 的 36:Address.sol
pragma solidity ^0.8.1;
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);
}
}
}
文件 2 的 36:AddressRegistry.sol
pragma solidity 0.8.19;
import {Ownable} from "../utils/Ownable.sol";
import {IOracle} from "../interfaces/IOracle.sol";
import {IGovernanceModule} from "../interfaces/IGovernanceModule.sol";
abstract contract AddressRegistry is Ownable {
IOracle public oracleModule;
IGovernanceModule public immutable GOVERNANCE_MODULE;
address public RELAYER;
event OracleModuleUpdated(address indexed oracleModule);
constructor(address _govModule, address _relayer) {
GOVERNANCE_MODULE = IGovernanceModule(_govModule);
RELAYER = _relayer;
}
function setRelayer(address _relayer) external onlyOwner {
RELAYER = _relayer;
}
function setOracleModule(address _oracle) public onlyOwner {
oracleModule = IOracle(_oracle);
emit OracleModuleUpdated(_oracle);
}
}
文件 3 的 36:AssetRegistry.sol
pragma solidity 0.8.19;
import {AssetInfo} from "./Structs.sol";
import {AddressRegistry} from "./AddressRegistry.sol";
import {ProtocolState} from "./ProtocolState.sol";
import {Ownable} from "../utils/Ownable.sol";
import {BaseChecker} from "../utils/BaseChecker.sol";
import {IERC20Metadata} from "openzeppelin-contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {IUniswapV3PoolImmutables} from
"lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol";
import {IRelayer} from "src/interfaces/IRelayer.sol";
abstract contract AssetRegistry is Ownable, BaseChecker, AddressRegistry, ProtocolState {
address[] public assetsList;
uint128 public lastIncentiveUpdateBlock;
int128 public incentiveCap;
mapping(address => AssetInfo) public assetInfo;
error PoolNotValid();
error AssetSupported(address asset);
error NotNormalized();
error NotZero();
error CoolDownPeriodActive();
event AssetAdded(address _asset);
event IncentiveFactorUpdated(address indexed asset, int72 incentiveFactor);
event TargetConcentrationsUpdated();
event UniswapPoolUpdated(address indexed asset, address uniswapPool);
event AssetRemoved(address indexed asset);
function addAssets(address[] calldata _assets, address[] calldata _uniswapPools)
external
onlyOwner
{
if (_assets.length != _uniswapPools.length) revert InconsistentLengths();
for (uint256 i; i < _assets.length; ++i) {
_addAsset(_assets[i], _uniswapPools[i]);
}
}
function _addAsset(address _asset, address _uniswapPool) private {
if (assetInfo[_asset].isSupported) revert AssetSupported(_asset);
assetInfo[_asset].isSupported = true;
assetInfo[_asset].assetDecimals = IERC20Metadata(_asset).decimals();
setUniswapPool(_asset, _uniswapPool);
assetsList.push(_asset);
emit AssetAdded(_asset);
}
function removeAsset(uint256 _assetIdx) external onlyOwner {
address asset = assetsList[_assetIdx];
if (totalAssetAccounting[asset] != 0) revert NotZero();
if (assetInfo[asset].targetConcentration != 0) revert NotZero();
delete assetInfo[asset];
assetsList[_assetIdx] = assetsList[assetsList.length - 1];
assetsList.pop();
emit AssetRemoved(asset);
}
function setTargetConcentrations(uint72[] calldata _targetConcentrations) external onlyOwner {
if (_targetConcentrations.length != assetsList.length) revert InconsistentLengths();
uint72 sum;
for (uint256 i; i < _targetConcentrations.length; i++) {
sum += _targetConcentrations[i];
}
if (sum > (1e20 + 1e10) || sum < (1e20 - 1e10)) revert NotNormalized();
for (uint256 i; i < _targetConcentrations.length; i++) {
assetInfo[assetsList[i]].targetConcentration = _targetConcentrations[i];
}
emit TargetConcentrationsUpdated();
}
function setIncentiveFactor(address _asset, int72 _incentiveFactor) external onlyIncentiveManager {
if (int128(_incentiveFactor) > incentiveCap) revert ValueOutOfBounds();
if (block.number < uint256(lastIncentiveUpdateBlock) + 5) revert CoolDownPeriodActive();
lastIncentiveUpdateBlock = uint128(block.number);
assetInfo[_asset].incentiveFactor = _incentiveFactor;
emit IncentiveFactorUpdated(_asset, _incentiveFactor);
}
function setIncentiveCap(int128 _incentiveCap) external onlyOwner {
if (_incentiveCap > 1e20) revert ValueOutOfBounds();
incentiveCap = _incentiveCap;
}
function setUniswapPool(address _asset, address _uniswapPool) public onlyOwner {
if (_uniswapPool == address(0x0)) {
assetInfo[_asset].uniswapPool = _uniswapPool;
} else {
address token0 = IUniswapV3PoolImmutables(_uniswapPool).token0();
address token1 = IUniswapV3PoolImmutables(_uniswapPool).token1();
address quoteToken;
if (token0 == _asset) quoteToken = token1;
else if (token1 == _asset) quoteToken = token0;
else revert PoolNotValid();
assetInfo[_asset].uniswapPool = _uniswapPool;
assetInfo[_asset].uniswapQuoteToken = quoteToken;
assetInfo[_asset].quoteTokenDecimals = IERC20Metadata(quoteToken).decimals();
}
emit UniswapPoolUpdated(_asset, _uniswapPool);
}
function isAnyNotSupported(address[] memory _assets) public view returns (address) {
for (uint256 i; i < _assets.length; i++) {
if (!assetInfo[_assets[i]].isSupported) return _assets[i];
}
return address(0x0);
}
function isSwapAllowed(address[] memory _assets) public view returns (address) {
for (uint256 i; i < _assets.length; i++) {
if (assetInfo[_assets[i]].incentiveFactor == -100e18) return _assets[i];
}
return address(0x0);
}
function getAssetDecimals(address _asset) external view returns (uint8) {
return assetInfo[_asset].assetDecimals;
}
function getAssetsListLength() public view returns (uint256) {
return assetsList.length;
}
modifier onlyIncentiveManager() {
if (!IRelayer(RELAYER).isIncentiveManager(msg.sender)) revert Unauthorized();
_;
}
}
文件 4 的 36:BaseChecker.sol
pragma solidity 0.8.19;
abstract contract BaseChecker {
error ZeroParameter();
error InconsistentLengths();
function _checkZeroValue(uint256 val) internal pure {
if (val == 0) revert ZeroParameter();
}
function _checkZeroAddress(address addr) internal pure {
if (addr == address(0x0)) revert ZeroParameter();
}
function _checkForConsistentLength(address[] memory arr1, uint256[] memory arr2) internal pure {
if (arr1.length != arr2.length) revert InconsistentLengths();
}
}
文件 5 的 36:ERC20.sol
pragma solidity >=0.8.0;
abstract contract ERC20 {
event Transfer(address indexed from, address indexed to, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 amount);
string public name;
string public symbol;
uint8 public immutable decimals;
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
uint256 internal immutable INITIAL_CHAIN_ID;
bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;
mapping(address => uint256) public nonces;
constructor(
string memory _name,
string memory _symbol,
uint8 _decimals
) {
name = _name;
symbol = _symbol;
decimals = _decimals;
INITIAL_CHAIN_ID = block.chainid;
INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
}
function approve(address spender, uint256 amount) public virtual returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transfer(address to, uint256 amount) public virtual returns (bool) {
balanceOf[msg.sender] -= amount;
unchecked {
balanceOf[to] += amount;
}
emit Transfer(msg.sender, to, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual returns (bool) {
uint256 allowed = allowance[from][msg.sender];
if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;
balanceOf[from] -= amount;
unchecked {
balanceOf[to] += amount;
}
emit Transfer(from, to, amount);
return true;
}
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");
unchecked {
address recoveredAddress = ecrecover(
keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR(),
keccak256(
abi.encode(
keccak256(
"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
),
owner,
spender,
value,
nonces[owner]++,
deadline
)
)
)
),
v,
r,
s
);
require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");
allowance[recoveredAddress][spender] = value;
}
emit Approval(owner, spender, value);
}
function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
}
function computeDomainSeparator() internal view virtual returns (bytes32) {
return
keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes(name)),
keccak256("1"),
block.chainid,
address(this)
)
);
}
function _mint(address to, uint256 amount) internal virtual {
totalSupply += amount;
unchecked {
balanceOf[to] += amount;
}
emit Transfer(address(0), to, amount);
}
function _burn(address from, uint256 amount) internal virtual {
balanceOf[from] -= amount;
unchecked {
totalSupply -= amount;
}
emit Transfer(from, address(0), amount);
}
}
文件 6 的 36:Fyde.sol
pragma solidity 0.8.19;
import {TRSY} from "./core/TRSY.sol";
import {AssetRegistry} from "./core/AssetRegistry.sol";
import {AddressRegistry} from "./core/AddressRegistry.sol";
import {ProtocolState} from "./core/ProtocolState.sol";
import {Tax} from "./core/Tax.sol";
import {GovernanceAccess} from "./core/GovernanceAccess.sol";
import {RequestData, ProcessParam, AssetInfo} from "./core/Structs.sol";
import {Ownable} from "./utils/Ownable.sol";
import {PercentageMath} from "./utils/PercentageMath.sol";
import {SafeERC20} from "openzeppelin-contracts/token/ERC20/utils/SafeERC20.sol";
import {IERC20} from "openzeppelin-contracts/token/ERC20/IERC20.sol";
import {IOracle} from "src/interfaces/IOracle.sol";
import {IRelayer} from "src/interfaces/IRelayer.sol";
contract Fyde is TRSY, AddressRegistry, ProtocolState, AssetRegistry, GovernanceAccess, Tax {
using SafeERC20 for IERC20;
event FeesCollected(address indexed recipient, uint256 trsyFeesCollected);
event Deposit(uint32 requestId, uint256 trsyPrice, uint256 usdDepositValue, uint256 trsyMinted);
event Withdraw(uint32 requestId, uint256 trsyPrice, uint256 usdWithdrawValue, uint256 trsyBurned);
event Swap(uint32 requestId, address assetOut, uint256 amountOut);
event ManagementFeeCollected(uint256 feeToMint);
error AumNotInRange();
error OnlyOneUpdatePerBlock();
error SlippageExceed();
error FydeBalanceInsufficient();
error InsufficientTRSYBalance();
error AssetPriceNotAvailable();
error SwapAmountNotAvailable();
error AssetNotSupported(address asset);
error SwapDisabled(address asset);
error AssetIsQuarantined(address asset);
constructor(
address _relayer,
address _oracleModule,
address _governanceModule,
uint16 _maxAumDeviationAllowed,
uint72 _taxFactor,
uint72 _managementFee
) Ownable(msg.sender) AddressRegistry(_governanceModule, _relayer) {
oracleModule = IOracle(_oracleModule);
updateMaxAumDeviationAllowed(_maxAumDeviationAllowed);
updateTaxFactor(_taxFactor);
updateManagementFee(_managementFee);
_updateLastFeeCollectionTime();
}
function collectFees(address _recipient, uint256 _amount) external onlyOwner {
_checkZeroAddress(_recipient);
_checkZeroValue(_amount);
balanceOf[address(this)] -= _amount;
balanceOf[_recipient] += _amount;
emit FeesCollected(_recipient, _amount);
}
function collectManagementFee() external {
uint256 feePerSecond = uint256(protocolData.managementFee / 31_557_600);
uint256 timePeriod = block.timestamp - protocolData.lastFeeCollectionTime;
if (timePeriod == 0) return;
uint256 feeToMint = feePerSecond * timePeriod * totalSupply / 1e18;
_updateLastFeeCollectionTime();
_mint(address(this), feeToMint);
emit ManagementFeeCollected(feeToMint);
}
function updateProtocolAUM(uint256 _aum) external {
if (msg.sender != RELAYER && msg.sender != owner) revert Unauthorized();
if (block.number == protocolData.lastAUMUpdateBlock) revert CoolDownPeriodActive();
protocolData.lastAUMUpdateBlock = uint48(block.number);
(, uint256 limitedAum) = _AumIsInRange(_aum);
_updateProtocolAUM(limitedAum);
}
function processDeposit(uint256 _protocolAUM, RequestData calldata _req)
external
onlyRelayer
returns (uint256)
{
_checkIsSupported(_req.assetIn);
_checkIsNotQuarantined(_req.assetIn);
(bool isInRange,) = _AumIsInRange(_protocolAUM);
if (!isInRange) revert AumNotInRange();
(
ProcessParam[] memory processParam,
uint256 sharesToMint,
uint256 taxInTRSY,
uint256 totalUsdDeposit
) = getProcessParamDeposit(_req, _protocolAUM);
if (_req.slippageChecker > sharesToMint) revert SlippageExceed();
for (uint256 i; i < _req.assetIn.length; i++) {
IERC20(_req.assetIn[i]).safeTransferFrom(_req.requestor, address(this), _req.amountIn[i]);
}
if (_req.keepGovRights) _govDeposit(_req, processParam);
else _standardDeposit(_req, sharesToMint);
if (taxInTRSY > 0) _mint(address(this), taxInTRSY);
_updateProtocolAUM(_protocolAUM + totalUsdDeposit);
uint256 trsyPrice = (1e18 * (_protocolAUM + totalUsdDeposit)) / totalSupply;
emit Deposit(_req.id, trsyPrice, totalUsdDeposit, sharesToMint);
return totalUsdDeposit;
}
function _standardDeposit(RequestData calldata _req, uint256 _sharesToMint) internal {
_increaseAssetTotalAmount(_req.assetIn, _req.amountIn);
_mint(_req.requestor, _sharesToMint);
}
function _govDeposit(RequestData calldata _req, ProcessParam[] memory _processParam) internal {
uint256[] memory sharesAfterTax = new uint256[](_req.assetIn.length);
uint256[] memory amountInAfterTax = new uint256[](_req.assetIn.length);
uint256 taxMultiplicator;
uint256 totalTrsy;
for (uint256 i; i < _req.assetIn.length; i++) {
taxMultiplicator = 1e18 * _processParam[i].sharesAfterTax / (_processParam[i].sharesBeforeTax);
amountInAfterTax[i] = _req.amountIn[i] * taxMultiplicator / 1e18;
sharesAfterTax[i] = _processParam[i].sharesAfterTax;
totalTrsy += sharesAfterTax[i];
}
address proxy = GOVERNANCE_MODULE.govDeposit(
_req.requestor, _req.assetIn, amountInAfterTax, sharesAfterTax, totalTrsy
);
for (uint256 i; i < _req.assetIn.length; i++) {
IERC20(_req.assetIn[i]).safeTransfer(proxy, amountInAfterTax[i]);
}
_increaseAssetTotalAmount(_req.assetIn, _req.amountIn);
_increaseAssetProxyAmount(_req.assetIn, amountInAfterTax);
_mint(address(GOVERNANCE_MODULE), totalTrsy);
}
function processWithdraw(uint256 _protocolAUM, RequestData calldata _req)
external
onlyRelayer
returns (uint256)
{
_checkIsSupported(_req.assetOut);
_checkIsNotQuarantined(_req.assetOut);
(bool isInRange,) = _AumIsInRange(_protocolAUM);
if (!isInRange) revert AumNotInRange();
uint256 totalUsdWithdraw;
uint256 totalSharesToBurn;
(totalUsdWithdraw, totalSharesToBurn) =
_req.keepGovRights ? _govWithdraw(_protocolAUM, _req) : _standardWithdraw(_protocolAUM, _req);
_decreaseAssetTotalAmount(_req.assetOut, _req.amountOut);
_updateProtocolAUM(_protocolAUM - totalUsdWithdraw);
uint256 trsyPrice =
totalSupply != 0 ? (1e18 * (_protocolAUM - totalUsdWithdraw)) / totalSupply : 0;
emit Withdraw(_req.id, trsyPrice, totalUsdWithdraw, totalSharesToBurn);
return totalUsdWithdraw;
}
function _govWithdraw(uint256 _protocolAUM, RequestData calldata _req)
internal
returns (uint256, uint256)
{
uint256 usdVal = getQuote(_req.assetOut[0], _req.amountOut[0]);
if (usdVal == 0) revert AssetPriceNotAvailable();
uint256 trsyToBurn = _convertToShares(usdVal, _protocolAUM);
if (_req.slippageChecker < trsyToBurn) revert SlippageExceed();
_burn(address(GOVERNANCE_MODULE), trsyToBurn);
_decreaseAssetProxyAmount(_req.assetOut, _req.amountOut);
GOVERNANCE_MODULE.govWithdraw(_req.requestor, _req.assetOut[0], _req.amountOut[0], trsyToBurn);
IERC20(_req.assetOut[0]).safeTransfer(_req.requestor, _req.amountOut[0]);
return (usdVal, trsyToBurn);
}
function _standardWithdraw(uint256 _protocolAUM, RequestData calldata _req)
internal
returns (uint256, uint256)
{
for (uint256 i = 0; i < _req.assetOut.length; i++) {
if (standardAssetAccounting(_req.assetOut[i]) < _req.amountOut[i]) {
revert FydeBalanceInsufficient();
}
}
(, uint256 totalSharesToBurn,, uint256 taxInTRSY, uint256 totalUsdWithdraw) =
getProcessParamWithdraw(_req, _protocolAUM);
if (totalSharesToBurn > _req.slippageChecker) revert SlippageExceed();
if (balanceOf[_req.requestor] < totalSharesToBurn) revert InsufficientTRSYBalance();
_burn(_req.requestor, totalSharesToBurn);
if (taxInTRSY > 0) _mint(address(this), taxInTRSY);
for (uint256 i = 0; i < _req.assetOut.length; i++) {
IERC20(_req.assetOut[i]).safeTransfer(_req.requestor, _req.amountOut[i]);
}
return (totalUsdWithdraw, totalSharesToBurn);
}
function processSwap(uint256 _protocolAUM, RequestData calldata _req)
external
onlyRelayer
returns (int256)
{
_checkIsSupported(_req.assetIn);
_checkIsSupported(_req.assetOut);
_checkIsNotQuarantined(_req.assetIn);
_checkIsNotQuarantined(_req.assetOut);
_checkIfSwapAllowed(_req.assetIn);
_checkIfSwapAllowed(_req.assetOut);
(bool isInRange,) = _AumIsInRange(_protocolAUM);
if (!isInRange) revert AumNotInRange();
(uint256 amountOut, int256 deltaAUM) =
getSwapAmountOut(_req.assetIn[0], _req.amountIn[0], _req.assetOut[0], _protocolAUM);
if (amountOut == 0) revert SwapAmountNotAvailable();
if (amountOut < _req.slippageChecker) revert SlippageExceed();
if (standardAssetAccounting(_req.assetOut[0]) < amountOut) revert FydeBalanceInsufficient();
uint256 aum;
if (deltaAUM > 0) {
aum = _protocolAUM + uint256(deltaAUM);
_mint(address(this), _convertToShares(uint256(deltaAUM), _protocolAUM));
} else if (deltaAUM < 0) {
aum = _protocolAUM - uint256(-deltaAUM);
uint256 trsyToBurn = _convertToShares(uint256(-deltaAUM), _protocolAUM);
trsyToBurn = balanceOf[address(this)] >= trsyToBurn ? trsyToBurn : balanceOf[address(this)];
if (trsyToBurn != 0) _burn(address(this), trsyToBurn);
} else {
aum = _protocolAUM;
}
_updateProtocolAUM(aum);
_increaseAssetTotalAmount(_req.assetIn[0], _req.amountIn[0]);
_decreaseAssetTotalAmount(_req.assetOut[0], amountOut);
IERC20(_req.assetIn[0]).safeTransferFrom(_req.requestor, address(this), _req.amountIn[0]);
IERC20(_req.assetOut[0]).safeTransfer(_req.requestor, amountOut);
emit Swap(_req.id, _req.assetOut[0], amountOut);
return deltaAUM;
}
function getQuote(address _asset, uint256 _amount) public view override returns (uint256) {
AssetInfo memory _assetInfo = assetInfo[_asset];
uint256 price = oracleModule.getPriceInUSD(_asset, _assetInfo);
return (_amount * price) / (10 ** _assetInfo.assetDecimals);
}
function getAssetAUM(address _asset) public view returns (uint256) {
return getQuote(_asset, totalAssetAccounting[_asset]);
}
function computeProtocolAUM() public view returns (uint256) {
address asset;
uint256 aum;
uint256 assetAUM;
address[] memory nAsset = assetsList;
uint256 length = nAsset.length;
for (uint256 i = 0; i < length; ++i) {
asset = nAsset[i];
if (totalAssetAccounting[asset] == 0) continue;
assetAUM = getAssetAUM(asset);
if (assetAUM == 0) return protocolData.aum;
aum += assetAUM;
}
return aum;
}
function getProcessParamDeposit(RequestData memory _req, uint256 _protocolAUM)
public
view
returns (
ProcessParam[] memory processParam,
uint256 sharesToMint,
uint256 taxInTRSY,
uint256 totalUsdDeposit
)
{
processParam = new ProcessParam[](_req.assetIn.length);
for (uint256 i; i < _req.assetIn.length; i++) {
uint256 usdVal = getQuote(_req.assetIn[i], _req.amountIn[i]);
if (usdVal == 0) revert AssetPriceNotAvailable();
processParam[i] = ProcessParam({
targetConc: assetInfo[_req.assetIn[i]].targetConcentration,
currentConc: _getAssetConcentration(_req.assetIn[i], _protocolAUM),
usdValue: usdVal,
sharesBeforeTax: _convertToShares(usdVal, _protocolAUM),
taxableAmount: 0,
taxInUSD: 0,
sharesAfterTax: 0
});
totalUsdDeposit += usdVal;
}
for (uint256 i; i < processParam.length; i++) {
processParam[i] =
_getDepositTax(processParam[i], _protocolAUM, totalUsdDeposit, protocolData.taxFactor);
processParam[i].sharesAfterTax =
_convertToShares(processParam[i].usdValue - processParam[i].taxInUSD, _protocolAUM);
sharesToMint += processParam[i].sharesAfterTax;
taxInTRSY += processParam[i].sharesBeforeTax - processParam[i].sharesAfterTax;
}
return (processParam, sharesToMint, taxInTRSY, totalUsdDeposit);
}
function getProcessParamWithdraw(RequestData calldata _req, uint256 _protocolAUM)
public
view
returns (
ProcessParam[] memory processParam,
uint256 totalSharesToBurn,
uint256 sharesToBurnBeforeTax,
uint256 taxInTRSY,
uint256 totalUsdWithdraw
)
{
processParam = new ProcessParam[](_req.assetOut.length);
for (uint256 i; i < _req.assetOut.length; i++) {
uint256 usdVal = getQuote(_req.assetOut[i], _req.amountOut[i]);
if (usdVal == 0) revert AssetPriceNotAvailable();
processParam[i] = ProcessParam({
targetConc: assetInfo[_req.assetOut[i]].targetConcentration,
currentConc: _getAssetConcentration(_req.assetOut[i], _protocolAUM),
usdValue: usdVal,
sharesBeforeTax: 0,
taxableAmount: 0,
taxInUSD: 0,
sharesAfterTax: 0
});
totalUsdWithdraw += usdVal;
}
for (uint256 i; i < processParam.length; i++) {
processParam[i] =
_getWithdrawTax(processParam[i], _protocolAUM, totalUsdWithdraw, protocolData.taxFactor);
taxInTRSY += _convertToShares(processParam[i].taxInUSD, _protocolAUM);
}
sharesToBurnBeforeTax = _convertToShares(totalUsdWithdraw, _protocolAUM);
totalSharesToBurn = sharesToBurnBeforeTax + taxInTRSY;
}
function getSwapAmountOut(
address _assetIn,
uint256 _amountIn,
address _assetOut,
uint256 _protocolAUM
) public view returns (uint256, int256) {
{
uint256 usdValIn = getQuote(_assetIn, _amountIn);
uint256 assetOutPrice = getQuote(_assetOut, 10 ** assetInfo[_assetOut].assetDecimals);
if (usdValIn == 0 || assetOutPrice == 0) return (0, int256(0));
}
ProcessParam memory processParamIn = ProcessParam({
targetConc: assetInfo[_assetIn].targetConcentration,
currentConc: _getAssetConcentration(_assetIn, _protocolAUM),
usdValue: getQuote(_assetIn, _amountIn),
sharesBeforeTax: 0,
taxableAmount: 0,
taxInUSD: 0,
sharesAfterTax: 0
});
ProcessParam memory processParamOut = ProcessParam({
targetConc: assetInfo[_assetOut].targetConcentration,
currentConc: _getAssetConcentration(_assetOut, _protocolAUM),
usdValue: 0,
sharesBeforeTax: 0,
taxableAmount: 0,
taxInUSD: 0,
sharesAfterTax: 0
});
uint256 usdAmountOut = _getSwapRate(
processParamIn,
processParamOut,
_protocolAUM,
protocolData.taxFactor,
assetInfo[_assetIn].incentiveFactor,
assetInfo[_assetOut].incentiveFactor
);
return (
1e18 * usdAmountOut / getQuote(_assetOut, 1e18),
int256(processParamIn.usdValue) - int256(usdAmountOut)
);
}
function _getAssetConcentration(address _asset, uint256 _protocolAUM)
internal
view
returns (uint256)
{
if (_protocolAUM == 0 && protocolData.aum == 0) return 0;
return (1e20 * getAssetAUM(_asset)) / _protocolAUM;
}
function _AumIsInRange(uint256 _keeperAUM) internal view returns (bool, uint256) {
uint16 maxAumDeviationAllowed = protocolData.maxAumDeviationAllowed;
uint256 currAum = protocolData.aum;
uint256 lowerBound = PercentageMath.percentSub(currAum, maxAumDeviationAllowed);
uint256 upperBound = PercentageMath.percentAdd(currAum, maxAumDeviationAllowed);
if (_keeperAUM < lowerBound) return (false, lowerBound);
if (_keeperAUM > upperBound) return (false, upperBound);
return (true, _keeperAUM);
}
function _checkIsSupported(address[] memory _assets) internal view {
address notSupportedAsset = isAnyNotSupported(_assets);
if (notSupportedAsset != address(0x0)) revert AssetNotSupported(notSupportedAsset);
}
function _checkIsNotQuarantined(address[] memory _assets) internal view {
address quarantinedAsset = IRelayer(RELAYER).isAnyQuarantined(_assets);
if (quarantinedAsset != address(0x0)) revert AssetIsQuarantined(quarantinedAsset);
}
function _checkIfSwapAllowed(address[] memory _assets) internal view {
address notAllowedAsset = isSwapAllowed(_assets);
if (notAllowedAsset != address(0x0)) revert SwapDisabled(notAllowedAsset);
}
modifier onlyRelayer() {
if (msg.sender != RELAYER) revert Unauthorized();
_;
}
}
文件 7 的 36:GovernanceAccess.sol
pragma solidity 0.8.19;
import {AddressRegistry} from "./AddressRegistry.sol";
import {AssetRegistry} from "./AssetRegistry.sol";
import {ProtocolState} from "./ProtocolState.sol";
import {TRSY} from "./TRSY.sol";
import {RebalanceParam} from "./Structs.sol";
import {IERC20} from "openzeppelin-contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "openzeppelin-contracts/token/ERC20/utils/SafeERC20.sol";
abstract contract GovernanceAccess is TRSY, AddressRegistry, ProtocolState, AssetRegistry {
using SafeERC20 for IERC20;
function transferAsset(address _asset, address _recipient, uint256 _amount)
external
onlyGovernance
{
IERC20(_asset).safeTransfer(_recipient, _amount);
}
function updateAssetProxyAmount(address _asset, uint256 _amount) external onlyGovernance {
proxyAssetAccounting[_asset] = _amount;
}
function getRebalanceParams(address _asset) external view returns (RebalanceParam memory) {
return RebalanceParam(
_asset,
totalAssetAccounting[_asset],
proxyAssetAccounting[_asset],
getQuote(_asset, 1e18),
0,
1e18 * protocolData.aum / totalSupply
);
}
function getQuote(address _asset, uint256 _amount) public view virtual returns (uint256);
modifier onlyGovernance() {
if (msg.sender != address(GOVERNANCE_MODULE)) revert Unauthorized();
_;
}
}
文件 8 的 36:IERC20.sol
pragma solidity ^0.8.0;
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);
}
文件 9 的 36:IERC20Metadata.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
interface IERC20Metadata is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
文件 10 的 36:IERC20Permit.sol
pragma solidity ^0.8.0;
interface IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
文件 11 的 36:IGovernanceModule.sol
pragma solidity 0.8.19;
interface IGovernanceModule {
function fyde() external view returns (address);
function proxyImplementation() external view returns (address);
function proxyBalance(address proxy, address asset) external view returns (uint256);
function strsyBalance(address _user, address _govToken) external view returns (uint256 balance);
function assetToStrsy(address _asset) external view returns (address);
function userToProxy(address _user) external view returns (address);
function proxyToUser(address _proxy) external view returns (address);
function isOnGovernanceWhitelist(address _asset) external view returns (bool);
function getAllGovUsers() external view returns (address[] memory);
function isAnyNotOnGovWhitelist(address[] calldata _assets) external view returns (address);
function getUserGTAllowance(uint256 _TRSYAmount, address _token) external view returns (uint256);
function govDeposit(
address _depositor,
address[] calldata _govToken,
uint256[] calldata _amount,
uint256[] calldata _amountTRSY,
uint256 _totalTRSY
) external returns (address proxy);
function govWithdraw(
address _user,
address _asset,
uint256 _amountToWithdraw,
uint256 _trsyToBurn
) external;
function onStrsyTransfer(address sender, address _recipient) external;
function unstakeGov(uint256 _amount, address _asset) external;
function rebalanceProxy(address _proxy, address _asset, address[] memory _usersToRebalance)
external;
}
文件 12 的 36:IOracle.sol
pragma solidity 0.8.19;
import {AssetInfo} from "../core/Structs.sol";
interface IOracle {
function getPriceInUSD(address, AssetInfo calldata) external view returns (uint256);
function getGweiPrice() external view returns (uint256);
}
文件 13 的 36:IRelayer.sol
pragma solidity 0.8.19;
import {RequestData, UserRequest} from "../core/Structs.sol";
interface IRelayer {
function getNumPendingRequest() external view returns (uint256);
function getRequest(uint64 idx) external view returns (RequestData memory);
function requestGovernanceWithdraw(
UserRequest memory _userRequest,
address _user,
uint256 _maxTRSYToPay
) external payable;
function requestWithdraw(UserRequest[] memory _userRequest, uint256 _maxTRSYToPay)
external
payable;
function requestDeposit(
UserRequest[] memory _userRequest,
bool _keepGovRights,
uint256 _minTRSYExpected
) external payable;
function requestSwap(
address _assetIn,
uint256 _amountIn,
address _assetOut,
uint256 _minAmountOut
) external payable;
function processRequests(uint256 _protocolAUM) external;
function isQuarantined(address _asset) external view returns (bool);
function isIncentiveManager(address _incentiveManager) external view returns (bool);
function MAX_ASSET_TO_REQUEST() external view returns (uint8);
function actionToGasUsage(bytes32 _actionHash) external view returns (uint256);
function isUser(address _asset) external view returns (bool);
function isAnyQuarantined(address[] memory _assets) external view returns (address);
}
文件 14 的 36:IUniswapV3PoolImmutables.sol
pragma solidity >=0.5.0;
interface IUniswapV3PoolImmutables {
function factory() external view returns (address);
function token0() external view returns (address);
function token1() external view returns (address);
function fee() external view returns (uint24);
function tickSpacing() external view returns (int24);
function maxLiquidityPerTick() external view returns (uint128);
}
文件 15 的 36:MathUtil.sol
pragma solidity 0.8.19;
library MathUtil {
function max(int256 a, int256 b) internal pure returns (int256) {
return a >= b ? a : b;
}
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
}
文件 16 的 36:Ownable.sol
pragma solidity 0.8.19;
abstract contract Ownable {
address public owner;
address public pendingOwner;
event OwnershipTransferred(address indexed user, address indexed newOner);
event OwnershipTransferStarted(address indexed user, address indexed newOwner);
event OwnershipTransferCanceled(address indexed pendingOwner);
error Unauthorized();
constructor(address _owner) {
owner = _owner;
emit OwnershipTransferred(address(0), _owner);
}
function transferOwnership(address newOwner) external onlyOwner {
pendingOwner = newOwner;
emit OwnershipTransferStarted(msg.sender, pendingOwner);
}
function acceptOwnership() external {
if (msg.sender != pendingOwner) revert Unauthorized();
address oldOwner = owner;
owner = pendingOwner;
delete pendingOwner;
emit OwnershipTransferred(oldOwner, owner);
}
function cancelTransferOwnership() external onlyOwner {
emit OwnershipTransferCanceled(pendingOwner);
delete pendingOwner;
}
modifier onlyOwner() {
if (msg.sender != owner) revert Unauthorized();
_;
}
}
文件 17 的 36:PercentageMath.sol
pragma solidity 0.8.19;
library PercentageMath {
uint256 internal constant PERCENTAGE_FACTOR = 1e4;
uint256 internal constant HALF_PERCENTAGE_FACTOR = 0.5e4;
uint256 internal constant MAX_UINT256 = 2 ** 256 - 1;
uint256 internal constant MAX_UINT256_MINUS_HALF_PERCENTAGE = 2 ** 256 - 1 - 0.5e4;
function _isInRange(uint256 valA, uint256 valB, uint256 deviationThreshold)
internal
pure
returns (bool)
{
uint256 lowerBound = percentSub(valA, deviationThreshold);
uint256 upperBound = percentAdd(valA, deviationThreshold);
if (valB < lowerBound || valB > upperBound) return false;
else return true;
}
function percentAdd(uint256 x, uint256 percentage) internal pure returns (uint256 y) {
assembly {
y := add(PERCENTAGE_FACTOR, percentage)
if or(
gt(percentage, sub(MAX_UINT256, PERCENTAGE_FACTOR)),
gt(x, div(MAX_UINT256_MINUS_HALF_PERCENTAGE, y))
) { revert(0, 0) }
y := div(add(mul(x, y), HALF_PERCENTAGE_FACTOR), PERCENTAGE_FACTOR)
}
}
function percentSub(uint256 x, uint256 percentage) internal pure returns (uint256 y) {
assembly {
y := sub(PERCENTAGE_FACTOR, percentage)
if or(
gt(percentage, PERCENTAGE_FACTOR), mul(y, gt(x, div(MAX_UINT256_MINUS_HALF_PERCENTAGE, y)))
) { revert(0, 0) }
y := div(add(mul(x, y), HALF_PERCENTAGE_FACTOR), PERCENTAGE_FACTOR)
}
}
}
文件 18 的 36:ProtocolState.sol
pragma solidity 0.8.19;
import {ProtocolData} from "./Structs.sol";
import {Ownable} from "../utils/Ownable.sol";
abstract contract ProtocolState is Ownable {
ProtocolData public protocolData;
mapping(address => uint256) public totalAssetAccounting;
mapping(address => uint256) public proxyAssetAccounting;
error ValueOutOfBounds();
event ProtocolAumUpdated(uint256);
event MaxAumDeviationAllowedUpdated(uint16);
event TaxFactorUpdated(uint72);
event ManagementFeeUpdated(uint72);
function standardAssetAccounting(address _asset) public view returns (uint256) {
return totalAssetAccounting[_asset] - proxyAssetAccounting[_asset];
}
function getProtocolAUM() external view returns (uint256) {
return protocolData.aum;
}
function updateMaxAumDeviationAllowed(uint16 threshold) public onlyOwner {
if (threshold < 10 || threshold > 500) revert ValueOutOfBounds();
protocolData.maxAumDeviationAllowed = threshold;
emit MaxAumDeviationAllowedUpdated(threshold);
}
function updateTaxFactor(uint72 _taxFactor) public onlyOwner {
if (_taxFactor > 100e18) revert ValueOutOfBounds();
protocolData.taxFactor = _taxFactor;
emit TaxFactorUpdated(_taxFactor);
}
function updateManagementFee(uint72 _annualFee) public onlyOwner {
if (_annualFee > 5e16) revert ValueOutOfBounds();
protocolData.managementFee = _annualFee;
emit ManagementFeeUpdated(_annualFee);
}
function _updateLastFeeCollectionTime() internal {
protocolData.lastFeeCollectionTime = uint48(block.timestamp);
}
function _updateProtocolAUM(uint256 _aum) internal {
protocolData.aum = _aum;
emit ProtocolAumUpdated(_aum);
}
function _increaseAssetTotalAmount(address[] memory _assets, uint256[] memory _amounts) internal {
for (uint256 i; i < _assets.length; i++) {
_increaseAssetTotalAmount(_assets[i], _amounts[i]);
}
}
function _increaseAssetTotalAmount(address _asset, uint256 _amount) internal {
totalAssetAccounting[_asset] += _amount;
}
function _increaseAssetProxyAmount(address[] memory _assets, uint256[] memory _amounts) internal {
for (uint256 i; i < _assets.length; i++) {
proxyAssetAccounting[_assets[i]] += _amounts[i];
}
}
function _decreaseAssetTotalAmount(address[] memory _assets, uint256[] memory _amounts) internal {
for (uint256 i; i < _assets.length; i++) {
_decreaseAssetTotalAmount(_assets[i], _amounts[i]);
}
}
function _decreaseAssetTotalAmount(address _asset, uint256 _amount) internal {
totalAssetAccounting[_asset] -= _amount;
}
function _decreaseAssetProxyAmount(address[] memory _assets, uint256[] memory _amounts) internal {
for (uint256 i; i < _assets.length; i++) {
proxyAssetAccounting[_assets[i]] -= _amounts[i];
}
}
}
文件 19 的 36:SafeCast.sol
pragma solidity >=0.8.11 <0.9.0;
import "./SafeCast/SafeCastU32.sol";
import "./SafeCast/SafeCastI32.sol";
import "./SafeCast/SafeCastI24.sol";
import "./SafeCast/SafeCastU56.sol";
import "./SafeCast/SafeCastI56.sol";
import "./SafeCast/SafeCastU64.sol";
import "./SafeCast/SafeCastI128.sol";
import "./SafeCast/SafeCastI256.sol";
import "./SafeCast/SafeCastU128.sol";
import "./SafeCast/SafeCastU160.sol";
import "./SafeCast/SafeCastU256.sol";
import "./SafeCast/SafeCastAddress.sol";
import "./SafeCast/SafeCastBytes32.sol";
文件 20 的 36:SafeCastAddress.sol
pragma solidity >=0.8.11 <0.9.0;
library SafeCastAddress {
function toBytes32(address x) internal pure returns (bytes32) {
return bytes32(uint256(uint160(x)));
}
}
文件 21 的 36:SafeCastBytes32.sol
pragma solidity >=0.8.11 <0.9.0;
library SafeCastBytes32 {
function toAddress(bytes32 x) internal pure returns (address) {
return address(uint160(uint256(x)));
}
function toUint(bytes32 x) internal pure returns (uint) {
return uint(x);
}
}
文件 22 的 36:SafeCastI128.sol
pragma solidity >=0.8.11 <0.9.0;
library SafeCastI128 {
error OverflowInt128ToUint128();
error OverflowInt128ToInt32();
function toUint(int128 x) internal pure returns (uint128) {
if (x < 0) {
revert OverflowInt128ToUint128();
}
return uint128(x);
}
function to256(int128 x) internal pure returns (int256) {
return int256(x);
}
function to32(int128 x) internal pure returns (int32) {
if (x < int(type(int32).min) || x > int(type(int32).max)) {
revert OverflowInt128ToInt32();
}
return int32(x);
}
function zero() internal pure returns (int128) {
return int128(0);
}
}
文件 23 的 36:SafeCastI24.sol
pragma solidity >=0.8.11 <0.9.0;
library SafeCastI24 {
function to256(int24 x) internal pure returns (int256) {
return int256(x);
}
}
文件 24 的 36:SafeCastI256.sol
pragma solidity >=0.8.11 <0.9.0;
library SafeCastI256 {
error OverflowInt256ToUint256();
error OverflowInt256ToInt128();
error OverflowInt256ToInt24();
function to128(int256 x) internal pure returns (int128) {
if (x < int256(type(int128).min) || x > int256(type(int128).max)) {
revert OverflowInt256ToInt128();
}
return int128(x);
}
function to24(int256 x) internal pure returns (int24) {
if (x < int256(type(int24).min) || x > int256(type(int24).max)) {
revert OverflowInt256ToInt24();
}
return int24(x);
}
function toUint(int256 x) internal pure returns (uint256) {
if (x < 0) {
revert OverflowInt256ToUint256();
}
return uint256(x);
}
function zero() internal pure returns (int256) {
return int256(0);
}
}
文件 25 的 36:SafeCastI32.sol
pragma solidity >=0.8.11 <0.9.0;
library SafeCastI32 {
error OverflowInt32ToUint32();
function toUint(int32 x) internal pure returns (uint32) {
if (x < 0) {
revert OverflowInt32ToUint32();
}
return uint32(x);
}
}
文件 26 的 36:SafeCastI56.sol
pragma solidity >=0.8.11 <0.9.0;
library SafeCastI56 {
error OverflowInt56ToInt24();
function to24(int56 x) internal pure returns (int24) {
if (x < int(type(int24).min) || x > int(type(int24).max)) {
revert OverflowInt56ToInt24();
}
return int24(x);
}
}
文件 27 的 36:SafeCastU128.sol
pragma solidity >=0.8.11 <0.9.0;
library SafeCastU128 {
error OverflowUint128ToInt128();
function to256(uint128 x) internal pure returns (uint256) {
return uint256(x);
}
function toInt(uint128 x) internal pure returns (int128) {
if (x > uint128(type(int128).max)) {
revert OverflowUint128ToInt128();
}
return int128(x);
}
function toBytes32(uint128 x) internal pure returns (bytes32) {
return bytes32(uint256(x));
}
}
文件 28 的 36:SafeCastU160.sol
pragma solidity >=0.8.11 <0.9.0;
library SafeCastU160 {
function to256(uint160 x) internal pure returns (uint256) {
return uint256(x);
}
}
文件 29 的 36:SafeCastU256.sol
pragma solidity >=0.8.11 <0.9.0;
library SafeCastU256 {
error OverflowUint256ToUint128();
error OverflowUint256ToInt256();
error OverflowUint256ToUint64();
error OverflowUint256ToUint32();
error OverflowUint256ToUint160();
function to128(uint256 x) internal pure returns (uint128) {
if (x > type(uint128).max) {
revert OverflowUint256ToUint128();
}
return uint128(x);
}
function to64(uint256 x) internal pure returns (uint64) {
if (x > type(uint64).max) {
revert OverflowUint256ToUint64();
}
return uint64(x);
}
function to32(uint256 x) internal pure returns (uint32) {
if (x > type(uint32).max) {
revert OverflowUint256ToUint32();
}
return uint32(x);
}
function to160(uint256 x) internal pure returns (uint160) {
if (x > type(uint160).max) {
revert OverflowUint256ToUint160();
}
return uint160(x);
}
function toBytes32(uint256 x) internal pure returns (bytes32) {
return bytes32(x);
}
function toInt(uint256 x) internal pure returns (int256) {
if (x > uint256(type(int256).max)) {
revert OverflowUint256ToInt256();
}
return int256(x);
}
}
文件 30 的 36:SafeCastU32.sol
pragma solidity >=0.8.11 <0.9.0;
library SafeCastU32 {
error OverflowUint32ToInt32();
function toInt(uint32 x) internal pure returns (int32) {
if (x > uint32(type(int32).max)) {
revert OverflowUint32ToInt32();
}
return int32(x);
}
function to256(uint32 x) internal pure returns (uint256) {
return uint256(x);
}
function to56(uint32 x) internal pure returns (uint56) {
return uint56(x);
}
}
文件 31 的 36:SafeCastU56.sol
pragma solidity >=0.8.11 <0.9.0;
library SafeCastU56 {
error OverflowUint56ToInt56();
function toInt(uint56 x) internal pure returns (int56) {
if (x > uint56(type(int56).max)) {
revert OverflowUint56ToInt56();
}
return int56(x);
}
}
文件 32 的 36:SafeCastU64.sol
pragma solidity >=0.8.11 <0.9.0;
library SafeCastU64 {
error OverflowUint64ToInt64();
function toInt(uint64 x) internal pure returns (int64) {
if (x > uint64(type(int64).max)) {
revert OverflowUint64ToInt64();
}
return int64(x);
}
}
文件 33 的 36:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";
library SafeERC20 {
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}
文件 34 的 36:Structs.sol
pragma solidity 0.8.19;
struct AssetInfo {
uint72 targetConcentration;
address uniswapPool;
int72 incentiveFactor;
uint8 assetDecimals;
uint8 quoteTokenDecimals;
address uniswapQuoteToken;
bool isSupported;
}
struct ProtocolData {
uint256 aum;
uint72 taxFactor;
uint16 maxAumDeviationAllowed;
uint48 lastAUMUpdateBlock;
uint72 managementFee;
uint48 lastFeeCollectionTime;
}
struct UserRequest {
address asset;
uint256 amount;
}
struct RequestData {
uint32 id;
address requestor;
address[] assetIn;
uint256[] amountIn;
address[] assetOut;
uint256[] amountOut;
bool keepGovRights;
uint256 slippageChecker;
}
struct RequestQ {
uint64 start;
uint64 end;
mapping(uint64 => RequestData) requestData;
}
struct ProcessParam {
uint256 targetConc;
uint256 currentConc;
uint256 usdValue;
uint256 taxableAmount;
uint256 taxInUSD;
uint256 sharesBeforeTax;
uint256 sharesAfterTax;
}
struct RebalanceParam {
address asset;
uint256 assetTotalAmount;
uint256 assetProxyAmount;
uint256 assetPrice;
uint256 sTrsyTotalSupply;
uint256 trsyPrice;
}
文件 35 的 36:TRSY.sol
pragma solidity 0.8.19;
import {ERC20} from "solmate/tokens/ERC20.sol";
abstract contract TRSY is ERC20 {
constructor() ERC20("TRSY", "TRSY", 18) {}
function _convertToShares(uint256 _usdValue, uint256 _usdAUM) internal view returns (uint256) {
uint256 supply = totalSupply;
return supply == 0 ? _usdValue : (_usdValue * supply) / _usdAUM;
}
}
文件 36 的 36:Tax.sol
pragma solidity 0.8.19;
import {ProcessParam} from "./Structs.sol";
import {MathUtil} from "../utils/MathUtil.sol";
import "synthetix-v3/utils/core-contracts/contracts/utils/SafeCast.sol";
abstract contract Tax {
using SafeCastU256 for uint256;
using SafeCastI256 for int256;
function _getDepositTax(
ProcessParam memory processParam,
uint256 protocolAUM,
uint256 totalUsdDeposit,
uint256 taxFactor
) internal pure returns (ProcessParam memory) {
if (processParam.targetConc == 0) {
processParam.taxInUSD = processParam.usdValue;
return processParam;
}
if (taxFactor == 0) return processParam;
processParam = _computeDepositTaxableAmount(processParam, protocolAUM, totalUsdDeposit);
if (processParam.taxableAmount == 0) return processParam;
processParam = _computeDepositTaxInUSD(processParam, protocolAUM, totalUsdDeposit, taxFactor);
return processParam;
}
function _getWithdrawTax(
ProcessParam memory processParam,
uint256 protocolAUM,
uint256 totalUsdWithdraw,
uint256 taxFactor
) internal pure returns (ProcessParam memory) {
if (taxFactor == 0) return processParam;
processParam = _computeWithdrawTaxableAmount(processParam, protocolAUM, totalUsdWithdraw);
if (processParam.taxableAmount == 0) return processParam;
processParam = _computeWithdrawTaxInUSD(processParam, protocolAUM, totalUsdWithdraw, taxFactor);
return processParam;
}
function _getSwapRate(
ProcessParam memory processParamIn,
ProcessParam memory processParamOut,
uint256 protocolAUM,
uint256 taxFactor,
int256 incentiveFactorIn,
int256 incentiveFactorOut
) internal pure returns (uint256) {
processParamIn = _getDepositTax(processParamIn, protocolAUM, 0, taxFactor);
int256 valIn = incentiveFactorIn
* int256(processParamIn.usdValue - processParamIn.taxableAmount) / int256(1e20);
uint256 withdrawValOut = valIn >= 0
? processParamIn.usdValue - processParamIn.taxInUSD + valIn.toUint()
: processParamIn.usdValue - processParamIn.taxInUSD - (-1 * valIn).toUint();
processParamOut.usdValue = withdrawValOut;
processParamOut = _getWithdrawTax(processParamOut, protocolAUM, 0, taxFactor);
int256 valOut =
incentiveFactorOut * int256(withdrawValOut - processParamOut.taxableAmount) / 1e20;
uint256 usdValOut = valOut >= 0
? withdrawValOut - processParamOut.taxInUSD + valOut.toUint()
: withdrawValOut - processParamOut.taxInUSD - (-1 * valOut).toUint();
return usdValOut;
}
function _computeDepositTaxableAmount(
ProcessParam memory processParam,
uint256 protocolAUM,
uint256 totalUsdDeposit
) internal pure returns (ProcessParam memory) {
int256 deltaConc = protocolAUM.toInt()
* (processParam.currentConc.toInt() - processParam.targetConc.toInt()) / 1e20;
int256 targetDeposit = totalUsdDeposit != 0
? processParam.targetConc.toInt() * totalUsdDeposit.toInt() / 1e20
: int256(0);
int256 tax = processParam.usdValue.toInt() + deltaConc - targetDeposit;
processParam.taxableAmount =
MathUtil.min(processParam.usdValue.toInt(), MathUtil.max(tax, int256(0))).toUint();
return processParam;
}
function _computeDepositTaxInUSD(
ProcessParam memory processParam,
uint256 protocolAUM,
uint256 totalUsdDeposit,
uint256 taxFactor
) internal pure returns (ProcessParam memory) {
uint256 numerator = (protocolAUM * processParam.currentConc / 1e20) + processParam.usdValue;
uint256 denominator = (protocolAUM + totalUsdDeposit) * processParam.targetConc / 1e20;
uint256 eq = (1e18 * numerator / denominator) - 1e18;
uint256 tmpRes = MathUtil.min(eq, 1e18);
uint256 taxPerc = taxFactor * tmpRes / 1e20;
processParam.taxInUSD = processParam.taxableAmount * taxPerc / 1e18;
return processParam;
}
function _computeWithdrawTaxableAmount(
ProcessParam memory processParam,
uint256 protocolAUM,
uint256 totalUsdWithdraw
) internal pure returns (ProcessParam memory) {
int256 deltaConc = protocolAUM.toInt()
* (processParam.currentConc.toInt() - processParam.targetConc.toInt()) / 1e20;
int256 targetDeposit = processParam.targetConc.toInt() * totalUsdWithdraw.toInt() / 1e20;
int256 tax = processParam.usdValue.toInt() - deltaConc - targetDeposit;
processParam.taxableAmount =
MathUtil.min(processParam.usdValue.toInt(), MathUtil.max(tax, int256(0))).toUint();
return processParam;
}
function _computeWithdrawTaxInUSD(
ProcessParam memory processParam,
uint256 protocolAUM,
uint256 totalUsdWithdraw,
uint256 taxFactor
) internal pure returns (ProcessParam memory) {
int256 numerator =
protocolAUM.toInt() * processParam.currentConc.toInt() / 1e20 - processParam.usdValue.toInt();
int256 denominator =
processParam.targetConc.toInt() * (protocolAUM.toInt() - totalUsdWithdraw.toInt()) / 1e20;
int256 tmpRes = 1e18 - (1e18 * numerator / denominator);
uint256 tmpRes2 = MathUtil.min(tmpRes.toUint(), 1e18);
uint256 taxPerc = taxFactor * tmpRes2 / 1e20;
processParam.taxInUSD = processParam.taxableAmount * taxPerc / 1e18;
return processParam;
}
}
{
"compilationTarget": {
"src/Fyde.sol": "Fyde"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":@uniswap/v3-core/=lib/v3-core/",
":@uniswap/v3-periphery/=lib/v3-periphery/",
":ds-test/=lib/forge-std/lib/ds-test/src/",
":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
":forge-std/=lib/forge-std/src/",
":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
":openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/",
":openzeppelin/=lib/openzeppelin-contracts/contracts/",
":solmate/=lib/solmate/src/",
":synthetix-v3/=lib/synthetix-v3/",
":v3-core/=lib/v3-core/contracts/",
":v3-periphery/=lib/v3-periphery/contracts/"
]
}
[{"inputs":[{"internalType":"address","name":"_relayer","type":"address"},{"internalType":"address","name":"_oracleModule","type":"address"},{"internalType":"address","name":"_governanceModule","type":"address"},{"internalType":"uint16","name":"_maxAumDeviationAllowed","type":"uint16"},{"internalType":"uint72","name":"_taxFactor","type":"uint72"},{"internalType":"uint72","name":"_managementFee","type":"uint72"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"AssetIsQuarantined","type":"error"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"AssetNotSupported","type":"error"},{"inputs":[],"name":"AssetPriceNotAvailable","type":"error"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"AssetSupported","type":"error"},{"inputs":[],"name":"AumNotInRange","type":"error"},{"inputs":[],"name":"CoolDownPeriodActive","type":"error"},{"inputs":[],"name":"FydeBalanceInsufficient","type":"error"},{"inputs":[],"name":"InconsistentLengths","type":"error"},{"inputs":[],"name":"InsufficientTRSYBalance","type":"error"},{"inputs":[],"name":"NotNormalized","type":"error"},{"inputs":[],"name":"NotZero","type":"error"},{"inputs":[],"name":"OnlyOneUpdatePerBlock","type":"error"},{"inputs":[],"name":"OverflowInt256ToUint256","type":"error"},{"inputs":[],"name":"OverflowUint256ToInt256","type":"error"},{"inputs":[],"name":"PoolNotValid","type":"error"},{"inputs":[],"name":"SlippageExceed","type":"error"},{"inputs":[],"name":"SwapAmountNotAvailable","type":"error"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"SwapDisabled","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"ValueOutOfBounds","type":"error"},{"inputs":[],"name":"ZeroParameter","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_asset","type":"address"}],"name":"AssetAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"}],"name":"AssetRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"requestId","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"trsyPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"usdDepositValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"trsyMinted","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"trsyFeesCollected","type":"uint256"}],"name":"FeesCollected","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"int72","name":"incentiveFactor","type":"int72"}],"name":"IncentiveFactorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"feeToMint","type":"uint256"}],"name":"ManagementFeeCollected","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint72","name":"","type":"uint72"}],"name":"ManagementFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"","type":"uint16"}],"name":"MaxAumDeviationAllowedUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oracleModule","type":"address"}],"name":"OracleModuleUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipTransferCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"","type":"uint256"}],"name":"ProtocolAumUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"requestId","type":"uint32"},{"indexed":false,"internalType":"address","name":"assetOut","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[],"name":"TargetConcentrationsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint72","name":"","type":"uint72"}],"name":"TaxFactorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"address","name":"uniswapPool","type":"address"}],"name":"UniswapPoolUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"requestId","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"trsyPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"usdWithdrawValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"trsyBurned","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GOVERNANCE_MODULE","outputs":[{"internalType":"contract IGovernanceModule","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RELAYER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_assets","type":"address[]"},{"internalType":"address[]","name":"_uniswapPools","type":"address[]"}],"name":"addAssets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"assetInfo","outputs":[{"internalType":"uint72","name":"targetConcentration","type":"uint72"},{"internalType":"address","name":"uniswapPool","type":"address"},{"internalType":"int72","name":"incentiveFactor","type":"int72"},{"internalType":"uint8","name":"assetDecimals","type":"uint8"},{"internalType":"uint8","name":"quoteTokenDecimals","type":"uint8"},{"internalType":"address","name":"uniswapQuoteToken","type":"address"},{"internalType":"bool","name":"isSupported","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"assetsList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancelTransferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"collectFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collectManagementFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"computeProtocolAUM","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"getAssetAUM","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"getAssetDecimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAssetsListLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"address","name":"requestor","type":"address"},{"internalType":"address[]","name":"assetIn","type":"address[]"},{"internalType":"uint256[]","name":"amountIn","type":"uint256[]"},{"internalType":"address[]","name":"assetOut","type":"address[]"},{"internalType":"uint256[]","name":"amountOut","type":"uint256[]"},{"internalType":"bool","name":"keepGovRights","type":"bool"},{"internalType":"uint256","name":"slippageChecker","type":"uint256"}],"internalType":"struct RequestData","name":"_req","type":"tuple"},{"internalType":"uint256","name":"_protocolAUM","type":"uint256"}],"name":"getProcessParamDeposit","outputs":[{"components":[{"internalType":"uint256","name":"targetConc","type":"uint256"},{"internalType":"uint256","name":"currentConc","type":"uint256"},{"internalType":"uint256","name":"usdValue","type":"uint256"},{"internalType":"uint256","name":"taxableAmount","type":"uint256"},{"internalType":"uint256","name":"taxInUSD","type":"uint256"},{"internalType":"uint256","name":"sharesBeforeTax","type":"uint256"},{"internalType":"uint256","name":"sharesAfterTax","type":"uint256"}],"internalType":"struct ProcessParam[]","name":"processParam","type":"tuple[]"},{"internalType":"uint256","name":"sharesToMint","type":"uint256"},{"internalType":"uint256","name":"taxInTRSY","type":"uint256"},{"internalType":"uint256","name":"totalUsdDeposit","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"address","name":"requestor","type":"address"},{"internalType":"address[]","name":"assetIn","type":"address[]"},{"internalType":"uint256[]","name":"amountIn","type":"uint256[]"},{"internalType":"address[]","name":"assetOut","type":"address[]"},{"internalType":"uint256[]","name":"amountOut","type":"uint256[]"},{"internalType":"bool","name":"keepGovRights","type":"bool"},{"internalType":"uint256","name":"slippageChecker","type":"uint256"}],"internalType":"struct RequestData","name":"_req","type":"tuple"},{"internalType":"uint256","name":"_protocolAUM","type":"uint256"}],"name":"getProcessParamWithdraw","outputs":[{"components":[{"internalType":"uint256","name":"targetConc","type":"uint256"},{"internalType":"uint256","name":"currentConc","type":"uint256"},{"internalType":"uint256","name":"usdValue","type":"uint256"},{"internalType":"uint256","name":"taxableAmount","type":"uint256"},{"internalType":"uint256","name":"taxInUSD","type":"uint256"},{"internalType":"uint256","name":"sharesBeforeTax","type":"uint256"},{"internalType":"uint256","name":"sharesAfterTax","type":"uint256"}],"internalType":"struct ProcessParam[]","name":"processParam","type":"tuple[]"},{"internalType":"uint256","name":"totalSharesToBurn","type":"uint256"},{"internalType":"uint256","name":"sharesToBurnBeforeTax","type":"uint256"},{"internalType":"uint256","name":"taxInTRSY","type":"uint256"},{"internalType":"uint256","name":"totalUsdWithdraw","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getProtocolAUM","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"getQuote","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"getRebalanceParams","outputs":[{"components":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"assetTotalAmount","type":"uint256"},{"internalType":"uint256","name":"assetProxyAmount","type":"uint256"},{"internalType":"uint256","name":"assetPrice","type":"uint256"},{"internalType":"uint256","name":"sTrsyTotalSupply","type":"uint256"},{"internalType":"uint256","name":"trsyPrice","type":"uint256"}],"internalType":"struct RebalanceParam","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_assetIn","type":"address"},{"internalType":"uint256","name":"_amountIn","type":"uint256"},{"internalType":"address","name":"_assetOut","type":"address"},{"internalType":"uint256","name":"_protocolAUM","type":"uint256"}],"name":"getSwapAmountOut","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"incentiveCap","outputs":[{"internalType":"int128","name":"","type":"int128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_assets","type":"address[]"}],"name":"isAnyNotSupported","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_assets","type":"address[]"}],"name":"isSwapAllowed","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastIncentiveUpdateBlock","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracleModule","outputs":[{"internalType":"contract IOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_protocolAUM","type":"uint256"},{"components":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"address","name":"requestor","type":"address"},{"internalType":"address[]","name":"assetIn","type":"address[]"},{"internalType":"uint256[]","name":"amountIn","type":"uint256[]"},{"internalType":"address[]","name":"assetOut","type":"address[]"},{"internalType":"uint256[]","name":"amountOut","type":"uint256[]"},{"internalType":"bool","name":"keepGovRights","type":"bool"},{"internalType":"uint256","name":"slippageChecker","type":"uint256"}],"internalType":"struct RequestData","name":"_req","type":"tuple"}],"name":"processDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_protocolAUM","type":"uint256"},{"components":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"address","name":"requestor","type":"address"},{"internalType":"address[]","name":"assetIn","type":"address[]"},{"internalType":"uint256[]","name":"amountIn","type":"uint256[]"},{"internalType":"address[]","name":"assetOut","type":"address[]"},{"internalType":"uint256[]","name":"amountOut","type":"uint256[]"},{"internalType":"bool","name":"keepGovRights","type":"bool"},{"internalType":"uint256","name":"slippageChecker","type":"uint256"}],"internalType":"struct RequestData","name":"_req","type":"tuple"}],"name":"processSwap","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_protocolAUM","type":"uint256"},{"components":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"address","name":"requestor","type":"address"},{"internalType":"address[]","name":"assetIn","type":"address[]"},{"internalType":"uint256[]","name":"amountIn","type":"uint256[]"},{"internalType":"address[]","name":"assetOut","type":"address[]"},{"internalType":"uint256[]","name":"amountOut","type":"uint256[]"},{"internalType":"bool","name":"keepGovRights","type":"bool"},{"internalType":"uint256","name":"slippageChecker","type":"uint256"}],"internalType":"struct RequestData","name":"_req","type":"tuple"}],"name":"processWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"protocolData","outputs":[{"internalType":"uint256","name":"aum","type":"uint256"},{"internalType":"uint72","name":"taxFactor","type":"uint72"},{"internalType":"uint16","name":"maxAumDeviationAllowed","type":"uint16"},{"internalType":"uint48","name":"lastAUMUpdateBlock","type":"uint48"},{"internalType":"uint72","name":"managementFee","type":"uint72"},{"internalType":"uint48","name":"lastFeeCollectionTime","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"proxyAssetAccounting","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assetIdx","type":"uint256"}],"name":"removeAsset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"int128","name":"_incentiveCap","type":"int128"}],"name":"setIncentiveCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"int72","name":"_incentiveFactor","type":"int72"}],"name":"setIncentiveFactor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oracle","type":"address"}],"name":"setOracleModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_relayer","type":"address"}],"name":"setRelayer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint72[]","name":"_targetConcentrations","type":"uint72[]"}],"name":"setTargetConcentrations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"address","name":"_uniswapPool","type":"address"}],"name":"setUniswapPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"standardAssetAccounting","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"totalAssetAccounting","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"transferAsset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"updateAssetProxyAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint72","name":"_annualFee","type":"uint72"}],"name":"updateManagementFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"threshold","type":"uint16"}],"name":"updateMaxAumDeviationAllowed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_aum","type":"uint256"}],"name":"updateProtocolAUM","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint72","name":"_taxFactor","type":"uint72"}],"name":"updateTaxFactor","outputs":[],"stateMutability":"nonpayable","type":"function"}]