编译器
0.8.23+commit.f704f362
文件 1 的 8:Address.sol
pragma solidity ^0.8.20;
library Address {
error AddressInsufficientBalance(address account);
error AddressEmptyCode(address target);
error FailedInnerCall();
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert AddressInsufficientBalance(address(this));
}
(bool success, ) = recipient.call{value: amount}("");
if (!success) {
revert FailedInnerCall();
}
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert AddressInsufficientBalance(address(this));
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
function _revert(bytes memory returndata) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert FailedInnerCall();
}
}
}
文件 2 的 8:Context.sol
pragma solidity ^0.8.20;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
文件 3 的 8:IERC20.sol
pragma solidity ^0.8.20;
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 value) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
文件 4 的 8:IRewarder.sol
pragma solidity =0.8.23;
interface IRewarder {
function currency() external view returns (address);
function onReward(address to, uint256 unoAmount, uint256 accumulatedAmount) external payable returns (uint256);
}
文件 5 的 8:Pausable.sol
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
abstract contract Pausable is Context {
bool private _paused;
event Paused(address account);
event Unpaused(address account);
error EnforcedPause();
error ExpectedPause();
constructor() {
_paused = false;
}
modifier whenNotPaused() {
_requireNotPaused();
_;
}
modifier whenPaused() {
_requirePaused();
_;
}
function paused() public view virtual returns (bool) {
return _paused;
}
function _requireNotPaused() internal view virtual {
if (paused()) {
revert EnforcedPause();
}
}
function _requirePaused() internal view virtual {
if (!paused()) {
revert ExpectedPause();
}
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
文件 6 的 8:ReentrancyGuard.sol
pragma solidity ^0.8.20;
abstract contract ReentrancyGuard {
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
error ReentrancyGuardReentrantCall();
constructor() {
_status = NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
_status = ENTERED;
}
function _nonReentrantAfter() private {
_status = NOT_ENTERED;
}
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}
文件 7 的 8:Rewarder.sol
pragma solidity =0.8.23;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/utils/Pausable.sol";
import "./interfaces/IRewarder.sol";
import "./libraries/TransferHelper.sol";
interface ISSIP {
struct PoolInfo {
uint256 lastRewardBlock;
uint256 accUnoPerShare;
uint256 unoMultiplierPerBlock;
}
struct UserInfo {
uint256 lastWithdrawTime;
uint256 rewardDebt;
uint256 amount;
}
function poolInfo() external view returns (PoolInfo memory);
function userInfo(address _user) external view returns (UserInfo memory);
function riskPool() external view returns (address);
}
contract Rewarder is IRewarder, ReentrancyGuard, Pausable {
using Address for address;
uint256 public constant ACC_UNO_PRECISION = 1e18;
address public immutable override currency;
address public immutable pool;
address public operator;
event LogRewarderWithdraw(address indexed _rewarder, address _currency, address indexed _to, uint256 _amount);
event LogTransferOwnerShip(address indexed _rewarder, address indexed _oldOperator, address indexed _newOperator);
constructor(address _operator, address _currency, address _pool) {
require(_operator != address(0), "UnoRe: zero operator address");
require(_pool != address(0), "UnoRe: zero pool address");
currency = _currency;
pool = _pool;
operator = _operator;
}
receive() external payable {}
function pausePool() external onlyOperator {
_pause();
}
function unpausePool() external onlyOperator {
_unpause();
}
function onReward(
address _to,
uint256 _amount,
uint256 _accumulatedAmount
) external payable override onlyPOOL whenNotPaused returns (uint256) {
ISSIP ssip = ISSIP(pool);
ISSIP.PoolInfo memory poolInfos = ssip.poolInfo();
uint256 accumulatedUno = (_accumulatedAmount *
uint256(poolInfos.accUnoPerShare)) / ACC_UNO_PRECISION;
require(accumulatedUno > _amount, "UnoRe: invalid reward amount");
if (currency == address(0)) {
require(address(this).balance >= _amount, "UnoRe: insufficient reward balance");
TransferHelper.safeTransferETH(_to, _amount);
return _amount;
} else {
require(IERC20(currency).balanceOf(address(this)) >= _amount, "UnoRe: insufficient reward balance");
TransferHelper.safeTransfer(currency, _to, _amount);
return _amount;
}
}
function withdraw(address _to, uint256 _amount) external onlyOperator whenNotPaused {
require(_to != address(0), "UnoRe: zero address reward");
if (currency == address(0)) {
if (address(this).balance >= _amount) {
TransferHelper.safeTransferETH(_to, _amount);
emit LogRewarderWithdraw(address(this), currency, _to, _amount);
} else {
if (address(this).balance > 0) {
uint256 rewardAmount = address(this).balance;
TransferHelper.safeTransferETH(_to, address(this).balance);
emit LogRewarderWithdraw(address(this), currency, _to, rewardAmount);
}
}
} else {
if (IERC20(currency).balanceOf(address(this)) >= _amount) {
TransferHelper.safeTransfer(currency, _to, _amount);
emit LogRewarderWithdraw(address(this), currency, _to, _amount);
} else {
if (IERC20(currency).balanceOf(address(this)) > 0) {
uint256 rewardAmount = IERC20(currency).balanceOf(address(this));
TransferHelper.safeTransfer(currency, _to, IERC20(currency).balanceOf(address(this)));
emit LogRewarderWithdraw(address(this), currency, _to, rewardAmount);
}
}
}
}
function transferOwnership(address _to) external onlyOperator whenNotPaused {
require(_to != address(0), "UnoRe: zero address reward");
address oldOperator = operator;
operator = _to;
emit LogTransferOwnerShip(address(this), oldOperator, _to);
}
modifier onlyPOOL() {
require(msg.sender == pool, "Only SSRP or SSIP contract can call this function.");
_;
}
modifier onlyOperator() {
require(msg.sender == operator, "Only operator call this function.");
_;
}
}
文件 8 的 8:TransferHelper.sol
pragma solidity =0.8.23;
library TransferHelper {
function safeApprove(address token, address to, uint256 value) internal {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper::safeApprove: approve failed");
}
function safeTransfer(address token, address to, uint256 value) internal {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper::safeTransfer: transfer failed");
}
function safeTransferFrom(address token, address from, address to, uint256 value) internal {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper::transferFrom: transferFrom failed");
}
function safeTransferETH(address to, uint256 value) internal {
(bool success, ) = to.call{value: value}(new bytes(0));
require(success, "TransferHelper::safeTransferETH: ETH transfer failed");
}
}
{
"compilationTarget": {
"contracts/Rewarder.sol": "Rewarder"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_operator","type":"address"},{"internalType":"address","name":"_currency","type":"address"},{"internalType":"address","name":"_pool","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_rewarder","type":"address"},{"indexed":false,"internalType":"address","name":"_currency","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"LogRewarderWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_rewarder","type":"address"},{"indexed":true,"internalType":"address","name":"_oldOperator","type":"address"},{"indexed":true,"internalType":"address","name":"_newOperator","type":"address"}],"name":"LogTransferOwnerShip","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"ACC_UNO_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currency","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_accumulatedAmount","type":"uint256"}],"name":"onReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pausePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpausePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]