Address Contract Partially Verified
Address
0xC700000506423Bad12d5EB6D55b35EA9F5384Df6
Balance
0 ETH
Nonce
1
Code Size
5663 bytes
Creator
0xA00D3ba3...E80E at tx 0x94c79307...eb5355
Indexed Transactions
0
Contract Bytecode
5663 bytes
0x6080806040526004361015610012575f80fd5b5f3560e01c9081630d2aa245146105a75750806322d083211461058b578063249d39e91461056f57806357d775f814610535578063647846a5146104f157806365401e64146104a35780636cbdec7d14610456578063757991a8146103e8578063767bc1bf146102a757806378e979251461026d5780637b103999146102295780638da5cb5b14610114578063d42553c814610172578063e4fc6b6d14610158578063f2f4eb26146101145763fa443b53146100cc575f80fd5b34610110575f366003190112610110576040517f0000000000000000000000001099370bd8e48dd79a703f12ef59168c6ef8ad036001600160a01b03168152602090f35b5f80fd5b34610110575f366003190112610110576040517f000000000000000000000000c07e000044f95655c11fda4cd37f70a94d7e0a7d6001600160a01b03168152602090f35b34610110575f366003190112610110576101706107b0565b005b34610110576020366003190112610110576004356101ba337f000000000000000000000000c07e000044f95655c11fda4cd37f70a94d7e0a7d6001600160a01b031614610627565b620f424081116101f4576020817fc723f3965b561ddea13852839c5130d896a2e2d85699e6840b13dd87b03ee3aa925f55604051908152a1005b60405162461bcd60e51b815260206004820152600d60248201526c696e76616c696420726174696f60981b6044820152606490fd5b34610110575f366003190112610110576040517f00000000000000000000000010101010e0c3171d894b71b3400668af311e7d946001600160a01b03168152602090f35b34610110575f3660031901126101105760206040517f0000000000000000000000000000000000000000000000000000000067d220008152f35b34610110576080366003190112610110576044356024356064356004356102f8337f000000000000000000000000c07e000044f95655c11fda4cd37f70a94d7e0a7d6001600160a01b031614610627565b6127106103128361030d8761030d88876107a3565b6107a3565b036103b2576001805464ffffffffff60781b607885901b1664ffffffffff9384166001600160a01b0319909216821769ffffffffff0000000000602888901b161764ffffffffff60501b605089901b161717909155604080519182529382166020820152938116928401929092521660608201527f2980979c260d641cb2f63191367b76d0669367a564cf78fe1a08a12681e9f9be9080608081010390a1005b60405162461bcd60e51b815260206004820152600e60248201526d696e76616c69642073706c69747360901b6044820152606490fd5b34610110575f36600319011261011057602061044e6104277f0000000000000000000000000000000000000000000000000000000067d22000426105e8565b7f0000000000000000000000000000000000000000000000000000000000093a8090610609565b604051908152f35b34610110575f366003190112610110576001546040805164ffffffffff8084168252602884901c81166020830152605084901c81169282019290925260789290921c166060820152608090f35b34610110576020366003190112610110576004355f526002602052606060405f2054604051906001600160401b03811682526001600160401b038160401c16602083015260801c6040820152f35b34610110575f366003190112610110576040517f00000000000000000000000057ab1e0003f623289cd798b1824be09a793e4bec6001600160a01b03168152602090f35b34610110575f3660031901126101105760206040517f0000000000000000000000000000000000000000000000000000000000093a808152f35b34610110575f3660031901126101105760206040516127108152f35b34610110575f3660031901126101105760205f54604051908152f35b34610110575f366003190112610110577f000000000000000000000000aaaa0013e2ec451f76816d1e0a02aba596dd92516001600160a01b03168152602090f35b919082039182116105f557565b634e487b7160e01b5f52601160045260245ffd5b8115610613570490565b634e487b7160e01b5f52601260045260245ffd5b1561062e57565b60405162461bcd60e51b815260206004820152600560248201526421636f726560d81b6044820152606490fd5b606081019081106001600160401b0382111761067657604052565b634e487b7160e01b5f52604160045260245ffd5b90601f801991011681019081106001600160401b0382111761067657604052565b9081602091031261011057516001600160a01b03811681036101105790565b51906001600160401b038216820361011057565b908160609103126101105760408051916106f78361065b565b610700816106ca565b835261070e602082016106ca565b602084015201516001600160801b038116810361011057604082015290565b906001600160401b03809116911603906001600160401b0382116105f557565b906001600160401b03809116911602906001600160401b0382169182036105f557565b906001600160801b03809116911601906001600160801b0382116105f557565b818102929181159184041417156105f557565b919082018092116105f557565b604051630abca72960e41b81526020816004817f00000000000000000000000010101010e0c3171d894b71b3400668af311e7d946001600160a01b03165afa80156115e8575f915f916115f3575b506001600160a01b0316803b15610110575f80916004604051809481936305dabd6960e51b83525af180156115e8576115d5575b506108606104277f0000000000000000000000000000000000000000000000000000000067d22000426105e8565b600281106115d1576040516370a0823160e01b8152306004820152906020826024817f00000000000000000000000057ab1e0003f623289cd798b1824be09a793e4bec6001600160a01b03165afa9182156115c6578392611592575b508181600119810111611248577f0000000000000000000000001099370bd8e48dd79a703f12ef59168c6ef8ad036001600160a01b03163b1561156e5760405163073dd8e160e11b815260011983016004820152602481018290528481604481837f0000000000000000000000001099370bd8e48dd79a703f12ef59168c6ef8ad036001600160a01b03165af180156115725790859161157d575b50507f000000000000000000000000aaaa0013e2ec451f76816d1e0a02aba596dd92516001600160a01b03163b1561156e5760405163521ef18d60e11b81528481600481837f000000000000000000000000aaaa0013e2ec451f76816d1e0a02aba596dd92516001600160a01b03165af1801561157257908591611559575b5050839160011981018552600260205260408520604051906109f78261065b565b546001600160401b03811682526001600160401b038160401c16602083015260801c6040820152604051610a2a8161065b565b86815260208082018890526040808301899052516362982fb560e01b815290816004817f000000000000000000000000aaaa0013e2ec451f76816d1e0a02aba596dd92516001600160a01b03165afa90811561154e57889161151c575b50805f1981011161129d576001600160401b03835116806112b1575b506001600160401b0342811660208401525f19918201168252830183811161129d578752600260205260408720906001600160401b0381511690825491896fffffffffffffffff0000000000000000602084015160401b169260406001600160801b031991015160801b16931617171790556001600160801b0360408201511661116b575b505050604051608081018181106001600160401b038211176111575790610b9791604052610bb3612710610bab64ffffffffff82610ba18282600154998a99836060818d169283815282602082019e8f828260281c16905260501c166040820152019c60781c168c528d610790565b049751168a610790565b0495511687610790565b0480946107a3565b6040516361d027b360e01b815294906020866004817f00000000000000000000000010101010e0c3171d894b71b3400668af311e7d946001600160a01b03165afa958615610f7a578796611136575b5060405163a9059cbb60e01b88526001600160a01b039687166004526024859052956020908890604490829081907f00000000000000000000000057ab1e0003f623289cd798b1824be09a793e4bec165af160018851148116156110ee575b8660405215610f895763bf40fac160e01b8652602060048701819052600660248801526514d4915554d160d21b6044880152866064817f00000000000000000000000010101010e0c3171d894b71b3400668af311e7d946001600160a01b03165afa958615610f7a5787966110cd575b5060405163a9059cbb60e01b88526001600160a01b03968716600452602491909152946020908790604490829081907f00000000000000000000000057ab1e0003f623289cd798b1824be09a793e4bec165af16001875114811615611085575b85604052156110495763670fb82160e01b85526020856004817f00000000000000000000000010101010e0c3171d894b71b3400668af311e7d946001600160a01b03165afa94851561103e57869561100d575b5060405163a9059cbb60e01b87526001600160a01b0395861660048190526024849052956020908890604490829081907f00000000000000000000000057ab1e0003f623289cd798b1824be09a793e4bec165af16001885114811615610fc5575b8160405215610f8957853b15610f855763082662a360e21b81528681600481838a5af18015610f7a57908791610f61575b505091610e2a610e2a92610e2f95946105e8565b6105e8565b60405163a9059cbb60e01b8452600483905260249190915290602083604481807f00000000000000000000000057ab1e0003f623289cd798b1824be09a793e4bec6001600160a01b03165af16001845114811615610f19575b8260405215610edd57803b15610ed95781600481858094633890080960e11b83525af18015610ece57610eb9575050565b610ec482809261068a565b610ecb5750565b80fd5b6040513d84823e3d90fd5b8280fd5b635274afe760e01b83527f00000000000000000000000057ab1e0003f623289cd798b1824be09a793e4bec6001600160a01b0316600452602483fd5b6001811516610f58573d157f00000000000000000000000057ab1e0003f623289cd798b1824be09a793e4bec6001600160a01b03163b15151616610e88565b823d85823e3d90fd5b81610f6b9161068a565b610f7657855f610e16565b8580fd5b6040513d89823e3d90fd5b8680fd5b635274afe760e01b87527f00000000000000000000000057ab1e0003f623289cd798b1824be09a793e4bec6001600160a01b0316600452602487fd5b6001811516611004573d157f00000000000000000000000057ab1e0003f623289cd798b1824be09a793e4bec6001600160a01b03163b15151616610de5565b503d87823e3d90fd5b61103091955060203d602011611037575b611028818361068a565b8101906106ab565b935f610d84565b503d61101e565b6040513d88823e3d90fd5b635274afe760e01b86527f00000000000000000000000057ab1e0003f623289cd798b1824be09a793e4bec6001600160a01b0316600452602486fd5b60018115166110c4573d157f00000000000000000000000057ab1e0003f623289cd798b1824be09a793e4bec6001600160a01b03163b15151616610d31565b853d88823e3d90fd5b6110e791965060203d60201161103757611028818361068a565b945f610cd1565b600181151661112d573d157f00000000000000000000000057ab1e0003f623289cd798b1824be09a793e4bec6001600160a01b03163b15151616610c61565b863d89823e3d90fd5b61115091965060203d60201161103757611028818361068a565b945f610c02565b634e487b7160e01b85526041600452602485fd5b60405163bf8ab9a760e01b8152600119909201600483015291935091506020826024817f0000000000000000000000001099370bd8e48dd79a703f12ef59168c6ef8ad036001600160a01b03165afa91821561129257849261125c575b506111e7620f4240916001600160801b03604087549201511690610790565b04620f42400180620f42401161124857620f42408202828104620f42401483151715611234579161121e6112249261122b94610609565b906105e8565b80926105e8565b905f8080610b28565b634e487b7160e01b85526011600452602485fd5b634e487b7160e01b84526011600452602484fd5b9091506020813d60201161128a575b816112786020938361068a565b810103126101105751906111e76111c8565b3d915061126b565b6040513d86823e3d90fd5b634e487b7160e01b88526011600452602488fd5b604051635a3c097960e11b815260048101919091526060816024817f000000000000000000000000aaaa0013e2ec451f76816d1e0a02aba596dd92516001600160a01b03165afa9081156115115789916114f2575b506001600160801b0361135a6113346001600160401b036020880151166001600160401b038551169061072d565b6001600160401b0361135384604087015116928260208801511661074d565b1690610770565b1660408281019190915251635a3c097960e11b81525f1983016004820152906060826024817f000000000000000000000000aaaa0013e2ec451f76816d1e0a02aba596dd92516001600160a01b03165afa9182156114e7578a926114b6575b506113d76001600160401b038351166001600160401b03421661072d565b906001600160401b038351166001600160401b038316016001600160401b0381116114a2576001600160801b03916001600160401b0360409216855282611437838701956001600160401b0361135384895116928260208c01511661074d565b168094520151169003906001600160801b03821161148e576114826001600160401b0393926001600160801b038561147a81839651168260208c0151169061072d565b169116610609565b16604084015290610aa3565b634e487b7160e01b8a52601160045260248afd5b634e487b7160e01b8c52601160045260248cfd5b6114d991925060603d6060116114e0575b6114d1818361068a565b8101906106de565b905f6113b9565b503d6114c7565b6040513d8c823e3d90fd5b61150b915060603d6060116114e0576114d1818361068a565b5f611306565b6040513d8b823e3d90fd5b90506020813d602011611546575b816115376020938361068a565b8101031261011057515f610a87565b3d915061152a565b6040513d8a823e3d90fd5b816115639161068a565b61156e57835f6109d6565b8380fd5b6040513d87823e3d90fd5b816115879161068a565b61156e57835f610957565b9091506020813d6020116115be575b816115ae6020938361068a565b810103126101105751905f6108bc565b3d91506115a1565b6040513d85823e3d90fd5b5050565b6115e191505f9061068a565b5f5f610832565b6040513d5f823e3d90fd5b61160c915060203d60201161103757611028818361068a565b5f6107fe56fea164736f6c634300081c000a
Verified Source Code Partial Match
Compiler: v0.8.28+commit.7893614a
EVM: cancun
Optimization: Yes (200 runs)
FeeDepositController.sol 185 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { SafeERC20 } from "../libraries/SafeERC20.sol";
import { IResupplyRegistry } from "../interfaces/IResupplyRegistry.sol";
import { IRewardHandler } from "../interfaces/IRewardHandler.sol";
import { IPriceWatcher } from "../interfaces/IPriceWatcher.sol";
import { IFeeDeposit } from "../interfaces/IFeeDeposit.sol";
import { CoreOwnable } from "../dependencies/CoreOwnable.sol";
import { EpochTracker } from 'src/dependencies/EpochTracker.sol';
import { IFeeLogger } from "../interfaces/IFeeLogger.sol";
contract FeeDepositController is CoreOwnable, EpochTracker{
using SafeERC20 for IERC20;
address public immutable registry;
address public immutable feeToken;
address public immutable priceWatcher;
uint256 public additionalFeeRatio;
uint256 public constant BPS = 10_000;
Splits public splits;
IFeeLogger public immutable feeLogger;
struct WeightData{
uint64 index;
uint64 timestamp;
uint128 avgWeighting;
}
mapping(uint256 => WeightData) public epochWeighting;
struct Splits {
uint40 insurance;
uint40 treasury;
uint40 platform;
uint40 stakedStable;
}
event SplitsSet(uint40 insurance, uint40 treasury, uint40 platform, uint40 stakedStable);
event AdditionalFeeRatioSet(uint256 ratio);
/**
* @param _core Core contract address
* @param _registry Registry contract address
* @param _additionalFee Cap on the amount of additional fees to direct to staked stable (1e6 = 100%)
* @param _insuranceSplit Insurance split percentage (in BPS)
* @param _treasurySplit Treasury split percentage (in BPS)
* @param _stakedStableSplit Staked stable split percentage (in BPS)
*/
constructor(
address _core,
address _registry,
uint256 _additionalFee,
uint256 _insuranceSplit,
uint256 _treasurySplit,
uint256 _stakedStableSplit
) CoreOwnable(_core) EpochTracker(_core){
require(_additionalFee <= 1e6, "invalid ratio");
registry = _registry;
additionalFeeRatio = _additionalFee;
emit AdditionalFeeRatioSet(_additionalFee);
feeToken = IResupplyRegistry(_registry).token();
priceWatcher = IResupplyRegistry(_registry).getAddress("PRICE_WATCHER");
feeLogger = IFeeLogger(IResupplyRegistry(_registry).getAddress("FEE_LOGGER"));
uint40 _platformSplit = uint40(BPS - _insuranceSplit - _treasurySplit - _stakedStableSplit);
_setSplits(_insuranceSplit, _treasurySplit, _platformSplit, _stakedStableSplit);
}
function distribute() external{
// Pull fees. Reverts when called multiple times in single epoch.
address feeDeposit = IResupplyRegistry(registry).feeDeposit();
IFeeDeposit(feeDeposit).distributeFees();
uint256 currentEpoch = getEpoch();
if(currentEpoch < 2) return;
uint256 balance = IERC20(feeToken).balanceOf(address(this));
//log TOTAL fees for current epoch - 2 since the balance here is what was accrued two epochs ago
feeLogger.logTotalFees(currentEpoch-2, balance);
//max sure price watcher is up to date
IPriceWatcher(priceWatcher).updatePriceData();
uint256 stakedStableAmount;
//process weighted fees for sreusd
//first need to look at weighting differences for currentEpoch-2 (which was logged at the beginning of epoch-1)
//and currentEpoch-1 (which is logged now but the data being logged is for the previous epoch)
//ex. if getEpoch is 2, we need to find and record the avg weight during epoch 1.
//we do that by looking at difference of (x-2) and (x-1), aka epoch 0 and 1
WeightData memory prevWeight = epochWeighting[currentEpoch - 2];
WeightData memory currentWeight;
uint256 latestIndex = IPriceWatcher(priceWatcher).priceDataLength() - 1;
//only calc if there is enough data to do so, the first execution will result in 0 avgWeighting
if(prevWeight.index > 0){
//offset by the timestamp of the previous distribution
IPriceWatcher.PriceData memory prevData = IPriceWatcher(priceWatcher).priceDataAtIndex(prevWeight.index);
uint64 dt = prevWeight.timestamp - prevData.timestamp;
prevData.totalWeight = prevData.totalWeight + (prevData.weight * dt);
//get latest data and extrapolate a new data point that uses latest's weight and the time difference between
//latest and block.timestamp
IPriceWatcher.PriceData memory latest = IPriceWatcher(priceWatcher).priceDataAtIndex(latestIndex);
dt = uint64(block.timestamp) - latest.timestamp;
latest.timestamp = latest.timestamp + dt;
latest.totalWeight = latest.totalWeight + (latest.weight * dt);
//get difference of total weight between these two points
uint256 dw = latest.totalWeight - prevData.totalWeight;
//dt will always be > 0
dt = latest.timestamp - prevWeight.timestamp;
currentWeight.avgWeighting = uint128(dw / dt);
}
//set the latest timestamp and index used
currentWeight.timestamp = uint64(block.timestamp);
currentWeight.index = uint64(latestIndex);
//write to state to be used in the following epoch
epochWeighting[currentEpoch - 1] = currentWeight;
//next calculate how much of the current balance should be sent to sreusd
//using currentEpoch - 2 as pair interest is trailing by two epochs
if(prevWeight.avgWeighting > 0){
//get total amount of fees collected in interest only
uint256 feesInInterest = feeLogger.epochInterestFees(currentEpoch-2);
//use weighting to determine how much of the max fee should be applied
uint256 useAddFeeRatio = additionalFeeRatio * prevWeight.avgWeighting / 1e6;
useAddFeeRatio = 1e6 + useAddFeeRatio; //turn something like 10% or 0.1 to 1.1
stakedStableAmount = feesInInterest - (feesInInterest * 1e6 / useAddFeeRatio);
balance -= stakedStableAmount;
}
Splits memory _splits = splits;
uint256 ipAmount = balance * _splits.insurance / BPS;
uint256 treasuryAmount = balance * _splits.treasury / BPS;
uint256 stakedStableSplitAmount = balance * _splits.stakedStable / BPS;
stakedStableAmount += stakedStableSplitAmount;
//treasury
address treasury = IResupplyRegistry(registry).treasury();
IERC20(feeToken).safeTransfer(treasury, treasuryAmount);
//staked stable
address staked = IResupplyRegistry(registry).getAddress("SREUSD");
IERC20(feeToken).safeTransfer(staked, stakedStableAmount);
//insurance pool
address rewardHandler = IResupplyRegistry(registry).rewardHandler();
IERC20(feeToken).safeTransfer(rewardHandler, ipAmount);
IRewardHandler(rewardHandler).queueInsuranceRewards();
//rsup stakers
IERC20(feeToken).safeTransfer(rewardHandler, balance - ipAmount - treasuryAmount - stakedStableSplitAmount);
IRewardHandler(rewardHandler).queueStakingRewards();
}
/// @notice The ```setAdditionalFeeRatio``` function sets the max additional fee ratio attributed to staked stable
/// @param _additionalFee max additional fee ratio (1e6 = 100%)
function setAdditionalFeeRatio(uint256 _additionalFee) external onlyOwner {
require(_additionalFee <= 1e6, "invalid ratio");
additionalFeeRatio = _additionalFee;
emit AdditionalFeeRatioSet(_additionalFee);
}
/// @notice The ```setSplits``` function sets the fee distribution splits between insurance, treasury, and platform
/// @param _insuranceSplit The percentage (in BPS) to send to insurance pool
/// @param _treasurySplit The percentage (in BPS) to send to treasury
/// @param _platformSplit The percentage (in BPS) to send to platform stakers
/// @param _stakedStableSplit The percentage (in BPS) to send to staked stable
function setSplits(uint256 _insuranceSplit, uint256 _treasurySplit, uint256 _platformSplit, uint256 _stakedStableSplit) external onlyOwner {
_setSplits(_insuranceSplit, _treasurySplit, _platformSplit, _stakedStableSplit);
}
function _setSplits(uint256 _insuranceSplit, uint256 _treasurySplit, uint256 _platformSplit, uint256 _stakedStableSplit) internal {
require(_insuranceSplit + _treasurySplit + _platformSplit + _stakedStableSplit == BPS, "invalid splits");
splits.insurance = uint40(_insuranceSplit);
splits.treasury = uint40(_treasurySplit);
splits.platform = uint40(_platformSplit);
splits.stakedStable = uint40(_stakedStableSplit);
emit SplitsSet(uint40(_insuranceSplit), uint40(_treasurySplit), uint40(_platformSplit), uint40(_stakedStableSplit));
}
}
IERC20.sol 79 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
SafeERC20.sol 67 lines
// SPDX-License-Identifier: ISC
pragma solidity ^0.8.19;
import { IERC20 } from "@openzeppelin/contracts/interfaces/IERC20.sol";
import { SafeERC20 as OZSafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
// solhint-disable avoid-low-level-calls
// solhint-disable max-line-length
/// @title SafeERC20 provides helper functions for safe transfers as well as safe metadata access
/// @author Library originally written by @Boring_Crypto github.com/boring_crypto, modified by Drake Evans (Frax Finance) github.com/drakeevans
/// @dev original: https://github.com/boringcrypto/BoringSolidity/blob/fed25c5d43cb7ce20764cd0b838e21a02ea162e9/contracts/libraries/BoringERC20.sol
library SafeERC20 {
bytes4 private constant SIG_SYMBOL = 0x95d89b41; // symbol()
bytes4 private constant SIG_NAME = 0x06fdde03; // name()
bytes4 private constant SIG_DECIMALS = 0x313ce567; // decimals()
function returnDataToString(bytes memory data) internal pure returns (string memory) {
if (data.length >= 64) {
return abi.decode(data, (string));
} else if (data.length == 32) {
uint8 i = 0;
while (i < 32 && data[i] != 0) {
i++;
}
bytes memory bytesArray = new bytes(i);
for (i = 0; i < 32 && data[i] != 0; i++) {
bytesArray[i] = data[i];
}
return string(bytesArray);
} else {
return "???";
}
}
/// @notice Provides a safe ERC20.symbol version which returns '???' as fallback string.
/// @param token The address of the ERC-20 token contract.
/// @return (string) Token symbol.
function safeSymbol(IERC20 token) internal view returns (string memory) {
(bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(SIG_SYMBOL));
return success ? returnDataToString(data) : "???";
}
/// @notice Provides a safe ERC20.name version which returns '???' as fallback string.
/// @param token The address of the ERC-20 token contract.
/// @return (string) Token name.
function safeName(IERC20 token) internal view returns (string memory) {
(bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(SIG_NAME));
return success ? returnDataToString(data) : "???";
}
/// @notice Provides a safe ERC20.decimals version which returns '18' as fallback value.
/// @param token The address of the ERC-20 token contract.
/// @return (uint8) Token decimals.
function safeDecimals(IERC20 token) internal view returns (uint8) {
(bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(SIG_DECIMALS));
return success && data.length == 32 ? abi.decode(data, (uint8)) : 18;
}
function safeTransfer(IERC20 token, address to, uint256 value) internal {
OZSafeERC20.safeTransfer(token, to, value);
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
OZSafeERC20.safeTransferFrom(token, from, to, value);
}
}
IResupplyRegistry.sol 74 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
interface IResupplyRegistry {
event AddPair(address pairAddress);
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
event SetDeployer(address deployer, bool _bool);
event DefaultSwappersSet(address[] addresses);
event EntryUpdated(string indexed key, address indexed addr);
event WithdrawTo(address indexed user, uint256 amount);
// Protected keys
function LIQUIDATION_HANDLER() external pure returns (string memory);
function FEE_DEPOSIT() external pure returns (string memory);
function REDEMPTION_HANDLER() external pure returns (string memory);
function INSURANCE_POOL() external pure returns (string memory);
function REWARD_HANDLER() external pure returns (string memory);
function TREASURY() external pure returns (string memory);
function STAKER() external pure returns (string memory);
function L2_MANAGER() external pure returns (string memory);
function VEST_MANAGER() external pure returns (string memory);
// Other public functions
function token() external view returns (address);
function govToken() external view returns (address);
function getAddress(string memory key) external view returns (address);
function getAllKeys() external view returns (string[] memory);
function getAllAddresses() external view returns (address[] memory);
function getProtectedKeys() external pure returns (string[] memory);
function keyExists(string memory) external view returns (bool);
function hashToKey(bytes32) external view returns (string memory);
function setAddress(string memory key, address addr) external;
function acceptOwnership() external;
function addPair(address _pairAddress) external;
function registeredPairs(uint256) external view returns (address);
function pairsByName(string memory) external view returns (address);
function registeredPairsLength() external view returns (uint256);
function getAllPairAddresses() external view returns (address[] memory _deployedPairsArray);
function defaultSwappers(uint256 _index) external view returns (address);
function owner() external view returns (address);
function pendingOwner() external view returns (address);
function renounceOwnership() external;
function transferOwnership(address newOwner) external;
function claimFees(address _pair) external;
function claimRewards(address _pair) external;
function claimInsuranceRewards() external;
function withdrawTo(address _asset, uint256 _amount, address _to) external;
function mint(address receiver, uint256 amount) external;
function burn(address target, uint256 amount) external;
function liquidationHandler() external view returns(address);
function feeDeposit() external view returns(address);
function redemptionHandler() external view returns(address);
function rewardHandler() external view returns(address);
function insurancePool() external view returns(address);
function setRewardClaimer(address _newAddress) external;
function setRedemptionHandler(address _newAddress) external;
function setFeeDeposit(address _newAddress) external;
function setLiquidationHandler(address _newAddress) external;
function setInsurancePool(address _newAddress) external;
function setStaker(address _newAddress) external;
function setTreasury(address _newAddress) external;
function staker() external view returns(address);
function treasury() external view returns(address);
function l2manager() external view returns(address);
function setRewardHandler(address _newAddress) external;
function setVestManager(address _newAddress) external;
function setDefaultSwappers(address[] memory _swappers) external;
function collateralId(address _collateral) external view returns(uint256);
function core() external view returns(address);
error NameMustBeUnique();
error ProtectedKey(string key);
}
IRewardHandler.sol 28 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
interface IRewardHandler{
event BaseMinimumWeightSet(uint256 bweight);
event MinimumWeightSet(address indexed user, uint256 mweight);
function checkNewRewards(address _pair) external;
function claimRewards(address _pair) external;
function claimInsuranceRewards() external;
function setPairWeight(address _pair, uint256 _amount) external;
function queueInsuranceRewards() external;
function queueStakingRewards() external;
function pairEmissions() external view returns(address);
function insuranceEmissions() external view returns(address);
function insuranceRevenue() external view returns(address);
function debtEmissionsReceiver() external view returns(address);
function insuranceEmissionReceiver() external view returns(address);
function priceWatcher() external view returns(address);
function feeLogger() external view returns(address);
function pairTimestamp(address _pair) external view returns(uint256);
function minimumWeights(address _pair) external view returns(uint256);
function migrateState(address _oldRewardHandler, bool _migrateTimestamp, bool _migrateMinWeights) external;
function stateMigrated() external view returns(bool);
function baseMinimumWeight() external view returns(uint256);
function setBaseMinimumWeight(uint256 _bweight) external;
function getPairRate(address _pair, uint256 _timespan, uint256 _amount) external view returns(uint256);
function setPairMinimumWeight(address _account, uint256 _amount) external;
}
IPriceWatcher.sol 24 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
interface IPriceWatcher {
struct PriceData{
uint64 timestamp;
uint64 weight;
uint128 totalWeight;
}
event NewPriceData(uint256 indexed index, uint64 timestamp, uint64 weight, uint128 weightedValue);
event OracleSet(address indexed oracle);
function UPDATE_INTERVAL() external view returns(uint256);
function registry() external view returns(address);
function oracle() external view returns(address);
function updatePriceData() external;
function priceDataLength() external view returns(uint256);
function priceDataAtIndex(uint256 i) external view returns(PriceData memory _pd);
function latestPriceData() external view returns(PriceData memory _pd);
function findPairPriceWeight(address _pair) external view returns(uint256);
function getCurrentWeight() external view returns(uint64);
function canUpdatePriceData() external view returns(bool);
function setOracle() external;
}
IFeeDeposit.sol 11 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
interface IFeeDeposit {
function operator() external view returns(address);
function lastDistributedEpoch() external view returns(uint256);
function setOperator(address _newAddress) external;
function distributeFees() external;
function incrementPairRevenue(uint256 _fees, uint256 _otherFees) external;
function getEpoch() external view returns(uint256);
}
CoreOwnable.sol 27 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
import {ICore} from "../interfaces/ICore.sol";
/**
@title Core Ownable
@author Prisma Finance (with edits by Resupply Finance)
@notice Contracts inheriting `CoreOwnable` have the same owner as `Core`.
The ownership cannot be independently modified or renounced.
*/
contract CoreOwnable {
ICore public immutable core;
constructor(address _core) {
core = ICore(_core);
}
modifier onlyOwner() {
require(msg.sender == address(core), "!core");
_;
}
function owner() public view returns (address) {
return address(core);
}
}
EpochTracker.sol 24 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
import "../interfaces/ICore.sol";
/**
@title EpochTracker
@dev Provides a unified `startTime` and `getEpoch`, used for tracking epochs.
*/
contract EpochTracker {
uint256 public immutable startTime;
/// @notice Length of an epoch, in seconds
uint256 public immutable epochLength;
constructor(address _core) {
startTime = ICore(_core).startTime();
epochLength = ICore(_core).epochLength();
}
function getEpoch() public view returns (uint256 epoch) {
return (block.timestamp - startTime) / epochLength;
}
}
IFeeLogger.sol 15 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
/// @title IFeeLogger
/// @notice Interface for FeeLogger
interface IFeeLogger {
event LogTotalFees(uint256 _epoch, uint256 _amount);
event LogInterestFees(address _pair, uint256 _epoch, uint256 _amount);
function logTotalFees(uint256 _epoch, uint256 _amount) external;
function logInterestFees(address _pair, uint256 _epoch, uint256 _amount) external;
function pairEpochWeightings(address _pair, uint256 _epoch) external view returns(uint256 _interestFees);
function epochInterestFees(uint256 _epoch) external view returns(uint256 _fees);
function epochTotalFees(uint256 _epoch) external view returns(uint256 _fees);
function registry() external view returns(address _registry);
}
IERC20.sol 6 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol)
pragma solidity >=0.4.16;
import {IERC20} from "../token/ERC20/IERC20.sol";
SafeERC20.sol 280 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC1363} from "../../../interfaces/IERC1363.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC-20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
/**
* @dev An operation with an ERC-20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
if (!_safeTransfer(token, to, value, true)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
if (!_safeTransferFrom(token, from, to, value, true)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {
return _safeTransfer(token, to, value, false);
}
/**
* @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {
return _safeTransferFrom(token, from, to, value, false);
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*
* NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function
* only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being
* set here.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
if (!_safeApprove(token, spender, value, false)) {
if (!_safeApprove(token, spender, 0, true)) revert SafeERC20FailedOperation(address(token));
if (!_safeApprove(token, spender, value, true)) revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
safeTransfer(token, to, value);
} else if (!token.transferAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target
* has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferFromAndCallRelaxed(
IERC1363 token,
address from,
address to,
uint256 value,
bytes memory data
) internal {
if (to.code.length == 0) {
safeTransferFrom(token, from, to, value);
} else if (!token.transferFromAndCall(from, to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.
* Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}
* once without retrying, and relies on the returned value to be true.
*
* Reverts if the returned value is other than `true`.
*/
function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
forceApprove(token, to, value);
} else if (!token.approveAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity `token.transfer(to, value)` call, relaxing the requirement on the return value: the
* return value is optional (but if data is returned, it must not be false).
*
* @param token The token targeted by the call.
* @param to The recipient of the tokens
* @param value The amount of token to transfer
* @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.
*/
function _safeTransfer(IERC20 token, address to, uint256 value, bool bubble) private returns (bool success) {
bytes4 selector = IERC20.transfer.selector;
assembly ("memory-safe") {
let fmp := mload(0x40)
mstore(0x00, selector)
mstore(0x04, and(to, shr(96, not(0))))
mstore(0x24, value)
success := call(gas(), token, 0, 0, 0x44, 0, 0x20)
// if call success and return is true, all is good.
// otherwise (not success or return is not true), we need to perform further checks
if iszero(and(success, eq(mload(0x00), 1))) {
// if the call was a failure and bubble is enabled, bubble the error
if and(iszero(success), bubble) {
returndatacopy(fmp, 0, returndatasize())
revert(fmp, returndatasize())
}
// if the return value is not true, then the call is only successful if:
// - the token address has code
// - the returndata is empty
success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))
}
mstore(0x40, fmp)
}
}
/**
* @dev Imitates a Solidity `token.transferFrom(from, to, value)` call, relaxing the requirement on the return
* value: the return value is optional (but if data is returned, it must not be false).
*
* @param token The token targeted by the call.
* @param from The sender of the tokens
* @param to The recipient of the tokens
* @param value The amount of token to transfer
* @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.
*/
function _safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value,
bool bubble
) private returns (bool success) {
bytes4 selector = IERC20.transferFrom.selector;
assembly ("memory-safe") {
let fmp := mload(0x40)
mstore(0x00, selector)
mstore(0x04, and(from, shr(96, not(0))))
mstore(0x24, and(to, shr(96, not(0))))
mstore(0x44, value)
success := call(gas(), token, 0, 0, 0x64, 0, 0x20)
// if call success and return is true, all is good.
// otherwise (not success or return is not true), we need to perform further checks
if iszero(and(success, eq(mload(0x00), 1))) {
// if the call was a failure and bubble is enabled, bubble the error
if and(iszero(success), bubble) {
returndatacopy(fmp, 0, returndatasize())
revert(fmp, returndatasize())
}
// if the return value is not true, then the call is only successful if:
// - the token address has code
// - the returndata is empty
success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))
}
mstore(0x40, fmp)
mstore(0x60, 0)
}
}
/**
* @dev Imitates a Solidity `token.approve(spender, value)` call, relaxing the requirement on the return value:
* the return value is optional (but if data is returned, it must not be false).
*
* @param token The token targeted by the call.
* @param spender The spender of the tokens
* @param value The amount of token to transfer
* @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.
*/
function _safeApprove(IERC20 token, address spender, uint256 value, bool bubble) private returns (bool success) {
bytes4 selector = IERC20.approve.selector;
assembly ("memory-safe") {
let fmp := mload(0x40)
mstore(0x00, selector)
mstore(0x04, and(spender, shr(96, not(0))))
mstore(0x24, value)
success := call(gas(), token, 0, 0, 0x44, 0, 0x20)
// if call success and return is true, all is good.
// otherwise (not success or return is not true), we need to perform further checks
if iszero(and(success, eq(mload(0x00), 1))) {
// if the call was a failure and bubble is enabled, bubble the error
if and(iszero(success), bubble) {
returndatacopy(fmp, 0, returndatasize())
revert(fmp, returndatasize())
}
// if the return value is not true, then the call is only successful if:
// - the token address has code
// - the returndata is empty
success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))
}
mstore(0x40, fmp)
}
}
}
ICore.sol 31 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
import { IAuthHook } from './IAuthHook.sol';
interface ICore {
struct OperatorAuth {
bool authorized;
IAuthHook hook;
}
event VoterSet(address indexed newVoter);
event OperatorExecuted(address indexed caller, address indexed target, bytes data);
event OperatorSet(address indexed caller, address indexed target, bool authorized, bytes4 selector, IAuthHook authHook);
function execute(address target, bytes calldata data) external returns (bytes memory);
function epochLength() external view returns (uint256);
function startTime() external view returns (uint256);
function voter() external view returns (address);
function ownershipTransferDeadline() external view returns (uint256);
function pendingOwner() external view returns (address);
function setOperatorPermissions(
address caller,
address target,
bytes4 selector,
bool authorized,
IAuthHook authHook
) external;
function setVoter(address newVoter) external;
function operatorPermissions(address caller, address target, bytes4 selector) external view returns (bool authorized, IAuthHook hook);
}
IERC1363.sol 86 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol)
pragma solidity >=0.6.2;
import {IERC20} from "./IERC20.sol";
import {IERC165} from "./IERC165.sol";
/**
* @title IERC1363
* @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].
*
* Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract
* after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.
*/
interface IERC1363 is IERC20, IERC165 {
/*
* Note: the ERC-165 identifier for this interface is 0xb0202a11.
* 0xb0202a11 ===
* bytes4(keccak256('transferAndCall(address,uint256)')) ^
* bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^
* bytes4(keccak256('approveAndCall(address,uint256)')) ^
* bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
*/
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @param data Additional data with no specified format, sent in call to `spender`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);
}
IAuthHook.sol 7 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
interface IAuthHook {
function preHook(address operator, address target, bytes calldata data) external returns (bool);
function postHook(bytes memory result, address operator, address target, bytes calldata data) external returns (bool);
}
IERC165.sol 6 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)
pragma solidity >=0.4.16;
import {IERC165} from "../utils/introspection/IERC165.sol";
IERC165.sol 25 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
Read Contract
BPS 0x249d39e9 → uint256
additionalFeeRatio 0x22d08321 → uint256
core 0xf2f4eb26 → address
epochLength 0x57d775f8 → uint256
epochWeighting 0x65401e64 → uint64, uint64, uint128
feeLogger 0xfa443b53 → address
feeToken 0x647846a5 → address
getEpoch 0x757991a8 → uint256
owner 0x8da5cb5b → address
priceWatcher 0x0d2aa245 → address
registry 0x7b103999 → address
splits 0x6cbdec7d → uint40, uint40, uint40, uint40
startTime 0x78e97925 → uint256
Write Contract 3 functions
These functions modify contract state and require a wallet transaction to execute.
distribute 0xe4fc6b6d
No parameters
setAdditionalFeeRatio 0xd42553c8
uint256 _additionalFee
setSplits 0x767bc1bf
uint256 _insuranceSplit
uint256 _treasurySplit
uint256 _platformSplit
uint256 _stakedStableSplit
Recent Transactions
No transactions found for this address