文件 1 的 13: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 functionCall(target, data, "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");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(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) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(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) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 13:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 3 的 13:CrossFarmingVault.sol
pragma solidity 0.8.9;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "sgn-v2-contracts/contracts/message/interfaces/IMessageBus.sol";
import "./interfaces/IMessage.sol";
import "./libraries/DataTypes.sol";
contract CrossFarmingVault is Ownable, Pausable, ReentrancyGuard {
using SafeERC20 for IERC20;
struct UserInfo {
uint256 amount;
uint256 lastActionTime;
}
struct PoolInfo {
IERC20 lpToken;
uint256 mcv2PoolId;
uint256 totalAmount;
}
PoolInfo[] public poolInfo;
address public messageBus;
address public immutable CROSS_FARMING_SENDER;
address public immutable CROSS_FARMING_RECEIVER;
address public operator;
uint64 public immutable BSC_CHAIN_ID;
mapping(IERC20 => bool) public exists;
mapping(address => mapping(uint256 => mapping(uint64 => uint256))) public deposits;
mapping(uint256 => uint256) public poolMapping;
mapping(uint256 => bool) public whitelistPool;
mapping(uint256 => mapping(address => UserInfo)) public userInfo;
mapping(address => mapping(uint256 => mapping(uint64 => bool))) public usedNonce;
event Pause();
event Unpause();
event AddedWhiteListPool(uint256 pid);
event AddedPool(address indexed lpToken, uint256 mockPoolId);
event OperatorUpdated(address indexed newOperator, address indexed oldOperator);
event Deposit(address indexed sender, uint256 pid, uint256 amount, uint64 nonce);
event Withdraw(address indexed sender, uint256 pid, uint256 amount, uint64 nonce);
event EmergencyWithdraw(address indexed sender, uint256 pid, uint256 amount, uint64 nonce);
event AckWithdraw(address indexed sender, uint256 pid, uint256 amount, uint64 nonce);
event FallbackDeposit(address indexed sender, uint256 pid, uint256 amount, uint64 nonce);
event FallbackWithdraw(address indexed sender, uint256 pid, uint256 amount, uint64 nonce);
event AckEmergencyWithdraw(address indexed sender, uint256 pid, uint256 amount, uint64 nonce);
constructor(
address _operator,
address _sender,
address _receiver,
uint64 _chainId
) {
operator = _operator;
CROSS_FARMING_SENDER = _sender;
CROSS_FARMING_RECEIVER = _receiver;
BSC_CHAIN_ID = _chainId;
messageBus = IMessage(CROSS_FARMING_SENDER).messageBus();
poolInfo.push(PoolInfo({lpToken: IERC20(address(0)), mcv2PoolId: 0, totalAmount: 0}));
}
modifier onlySender() {
require(msg.sender == CROSS_FARMING_SENDER, "not cross farming sender");
_;
}
modifier onlyOperator() {
require(msg.sender == operator, "not fallback operator");
_;
}
modifier onlyNotUsedNonce(
address _user,
uint256 _pid,
uint64 _nonce
) {
require(!usedNonce[_user][_pid][_nonce], "used nonce");
_;
}
modifier notContract() {
require(!_isContract(msg.sender), "contract not allowed");
require(msg.sender == tx.origin, "proxy contract not allowed");
_;
}
function addWhiteListPool(uint256 _mcv2Pid) public onlyOwner {
require(!whitelistPool[_mcv2Pid], "Added mcv2 pool id");
whitelistPool[_mcv2Pid] = true;
emit AddedWhiteListPool(_mcv2Pid);
}
function add(IERC20 _lpToken, uint256 _mcv2PoolId) public onlyOwner {
require(!exists[_lpToken], "Existed token");
require(whitelistPool[_mcv2PoolId], "Not whitelist pool");
require(poolMapping[_mcv2PoolId] == 0, "MCV2 pool already matched");
require(_lpToken.balanceOf(address(this)) >= 0, "Not ERC20 token");
poolInfo.push(PoolInfo({lpToken: _lpToken, mcv2PoolId: _mcv2PoolId, totalAmount: 0}));
exists[_lpToken] = true;
poolMapping[_mcv2PoolId] = poolInfo.length - 1;
emit AddedPool(address(_lpToken), _mcv2PoolId);
}
function deposit(uint256 _pid, uint256 _amount) external payable nonReentrant whenNotPaused notContract {
require(_amount > 0, "Nothing to deposit");
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
uint256 before = pool.lpToken.balanceOf(address(this));
pool.lpToken.safeTransferFrom(msg.sender, address(this), _amount);
_amount = pool.lpToken.balanceOf(address(this)) - before;
uint64 nonce = IMessage(CROSS_FARMING_SENDER).nonces(msg.sender, pool.mcv2PoolId);
bytes memory message = encodeMessage(
msg.sender,
pool.mcv2PoolId,
_amount,
DataTypes.MessageTypes.Deposit,
nonce
);
(bool success, ) = CROSS_FARMING_SENDER.call{value: msg.value}(
abi.encodeWithSignature("sendFarmMessage(bytes)", message)
);
require(success, "send deposit farm message failed");
pool.totalAmount = pool.totalAmount + _amount;
user.amount = user.amount + _amount;
user.lastActionTime = block.timestamp;
deposits[msg.sender][_pid][nonce] = _amount;
emit Deposit(msg.sender, _pid, _amount, nonce);
}
function withdraw(uint256 _pid, uint256 _amount) external payable nonReentrant notContract whenNotPaused {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
require(user.amount >= _amount && _amount > 0, "withdraw: Insufficient amount");
uint64 nonce = IMessage(CROSS_FARMING_SENDER).nonces(msg.sender, pool.mcv2PoolId);
bytes memory message = encodeMessage(
msg.sender,
pool.mcv2PoolId,
_amount,
DataTypes.MessageTypes.Withdraw,
nonce
);
(bool success, ) = CROSS_FARMING_SENDER.call{value: msg.value}(
abi.encodeWithSignature("sendFarmMessage(bytes)", message)
);
require(success, "send withdraw farm message failed");
emit Withdraw(msg.sender, _pid, _amount, nonce);
}
function emergencyWithdraw(uint256 _pid) external payable nonReentrant notContract whenNotPaused {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
uint256 amount = user.amount;
require(amount > 0, "No fund left");
uint64 nonce = IMessage(CROSS_FARMING_SENDER).nonces(msg.sender, pool.mcv2PoolId);
bytes memory message = encodeMessage(
msg.sender,
pool.mcv2PoolId,
amount,
DataTypes.MessageTypes.EmergencyWithdraw,
nonce
);
(bool success, ) = CROSS_FARMING_SENDER.call{value: msg.value}(
abi.encodeWithSignature("sendFarmMessage(bytes)", message)
);
require(success, "send emergencyWithdraw farm message failed");
emit EmergencyWithdraw(msg.sender, _pid, amount, nonce);
}
function ackWithdraw(
address _user,
uint256 _mcv2pid,
uint256 _amount,
uint64 _nonce
) external nonReentrant onlySender {
uint256 pid = poolMapping[_mcv2pid];
require(!usedNonce[_user][pid][_nonce], "used nonce");
PoolInfo storage pool = poolInfo[pid];
UserInfo storage user = userInfo[pid][_user];
require(user.amount >= _amount && _amount > 0, "ackWithdraw: Insufficient amount");
pool.totalAmount = pool.totalAmount - _amount;
user.amount -= _amount;
user.lastActionTime = block.timestamp;
usedNonce[_user][pid][_nonce] = true;
IERC20(pool.lpToken).safeTransfer(_user, _amount);
emit AckWithdraw(_user, pid, _amount, _nonce);
}
function ackEmergencyWithdraw(
address _user,
uint256 _mcv2pid,
uint64 _nonce
) external nonReentrant onlySender {
uint256 pid = poolMapping[_mcv2pid];
require(!usedNonce[_user][pid][_nonce], "used nonce");
PoolInfo storage pool = poolInfo[pid];
UserInfo storage user = userInfo[pid][_user];
uint256 withdrawAmount = user.amount;
pool.totalAmount -= withdrawAmount;
user.amount = 0;
user.lastActionTime = block.timestamp;
usedNonce[_user][pid][_nonce] = true;
IERC20(pool.lpToken).safeTransfer(_user, withdrawAmount);
emit AckEmergencyWithdraw(_user, pid, withdrawAmount, _nonce);
}
function fallbackDeposit(
address _user,
uint256 _pid,
uint256 _amount,
uint64 _nonce
) external onlyOperator onlyNotUsedNonce(_user, _pid, _nonce) {
require(deposits[_user][_pid][_nonce] == _amount, "withdraw amount not match staking record");
_fallback(_user, _pid, _amount, _nonce);
emit FallbackDeposit(_user, _pid, _amount, _nonce);
}
function fallbackWithdraw(
address _user,
uint256 _pid,
uint256 _amount,
uint64 _nonce
) external onlyOperator onlyNotUsedNonce(_user, _pid, _nonce) {
_fallback(_user, _pid, _amount, _nonce);
emit FallbackWithdraw(_user, _pid, _amount, _nonce);
}
function _fallback(
address _user,
uint256 _pid,
uint256 _amount,
uint64 _nonce
) internal {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][_user];
require(user.amount >= _amount && _amount > 0, "fallback: Insufficient amount");
pool.totalAmount = pool.totalAmount - _amount;
user.amount -= _amount;
user.lastActionTime = block.timestamp;
usedNonce[_user][_pid][_nonce] = true;
IERC20(pool.lpToken).safeTransfer(_user, _amount);
}
function setOperator(address _operator) external onlyOwner {
require(_operator != address(0), "Operator can't be zero address");
address temp = operator;
operator = _operator;
emit OperatorUpdated(operator, temp);
}
function poolLength() external view returns (uint256) {
return poolInfo.length;
}
function calcFee(bytes calldata _message) external view returns (uint256) {
return IMessageBus(messageBus).calcFee(_message);
}
function encodeMessage(
address _account,
uint256 _pid,
uint256 _amount,
DataTypes.MessageTypes _msgType,
uint64 _nonce
) public view returns (bytes memory) {
return
abi.encode(
DataTypes.CrossFarmRequest({
receiver: CROSS_FARMING_RECEIVER,
dstChainId: BSC_CHAIN_ID,
nonce: _nonce,
account: _account,
amount: _amount,
pid: _pid,
msgType: _msgType
})
);
}
function pause() external onlyOwner {
_pause();
emit Pause();
}
function unpause() external onlyOwner {
_unpause();
emit Unpause();
}
function _isContract(address addr) internal view returns (bool) {
uint256 size;
assembly {
size := extcodesize(addr)
}
return size > 0;
}
}
文件 4 的 13:DataTypes.sol
pragma solidity 0.8.9;
library DataTypes {
enum MessageTypes {
Deposit,
Withdraw,
EmergencyWithdraw
}
struct CrossFarmRequest {
address receiver;
uint64 dstChainId;
uint64 nonce;
address account;
uint256 pid;
uint256 amount;
MessageTypes msgType;
}
}
文件 5 的 13: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);
}
文件 6 的 13:IMessage.sol
pragma solidity 0.8.9;
interface IMessage {
function nonces(address account, uint256 pid) external returns (uint64);
function messageBus() external returns (address);
}
文件 7 的 13:IMessageBus.sol
pragma solidity >=0.8.0;
import "../libraries/MsgDataTypes.sol";
interface IMessageBus {
function liquidityBridge() external view returns (address);
function pegBridge() external view returns (address);
function pegBridgeV2() external view returns (address);
function pegVault() external view returns (address);
function pegVaultV2() external view returns (address);
function calcFee(bytes calldata _message) external view returns (uint256);
function sendMessage(
address _receiver,
uint256 _dstChainId,
bytes calldata _message
) external payable;
function sendMessageWithTransfer(
address _receiver,
uint256 _dstChainId,
address _srcBridge,
bytes32 _srcTransferId,
bytes calldata _message
) external payable;
function withdrawFee(
address _account,
uint256 _cumulativeFee,
bytes[] calldata _sigs,
address[] calldata _signers,
uint256[] calldata _powers
) external;
function executeMessageWithTransfer(
bytes calldata _message,
MsgDataTypes.TransferInfo calldata _transfer,
bytes[] calldata _sigs,
address[] calldata _signers,
uint256[] calldata _powers
) external payable;
function executeMessageWithTransferRefund(
bytes calldata _message,
MsgDataTypes.TransferInfo calldata _transfer,
bytes[] calldata _sigs,
address[] calldata _signers,
uint256[] calldata _powers
) external payable;
function executeMessage(
bytes calldata _message,
MsgDataTypes.RouteInfo calldata _route,
bytes[] calldata _sigs,
address[] calldata _signers,
uint256[] calldata _powers
) external payable;
}
文件 8 的 13:MsgDataTypes.sol
pragma solidity 0.8.9;
library MsgDataTypes {
enum BridgeSendType {
Null,
Liquidity,
PegDeposit,
PegBurn,
PegV2Deposit,
PegV2Burn,
PegV2BurnFrom
}
enum TransferType {
Null,
LqRelay,
LqWithdraw,
PegMint,
PegWithdraw,
PegV2Mint,
PegV2Withdraw
}
enum MsgType {
MessageWithTransfer,
MessageOnly
}
enum TxStatus {
Null,
Success,
Fail,
Fallback,
Pending
}
struct TransferInfo {
TransferType t;
address sender;
address receiver;
address token;
uint256 amount;
uint64 wdseq;
uint64 srcChainId;
bytes32 refId;
bytes32 srcTxHash;
}
struct RouteInfo {
address sender;
address receiver;
uint64 srcChainId;
bytes32 srcTxHash;
}
struct MsgWithTransferExecutionParams {
bytes message;
TransferInfo transfer;
bytes[] sigs;
address[] signers;
uint256[] powers;
}
struct BridgeTransferParams {
bytes request;
bytes[] sigs;
address[] signers;
uint256[] powers;
}
}
文件 9 的 13:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 10 的 13:Pausable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Pausable is Context {
event Paused(address account);
event Unpaused(address account);
bool private _paused;
constructor() {
_paused = false;
}
modifier whenNotPaused() {
_requireNotPaused();
_;
}
modifier whenPaused() {
_requirePaused();
_;
}
function paused() public view virtual returns (bool) {
return _paused;
}
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
文件 11 的 13:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
文件 12 的 13:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/draft-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 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
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");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
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");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
文件 13 的 13:draft-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);
}
{
"compilationTarget": {
"contracts/CrossFarmingVault.sol": "CrossFarmingVault"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 99999
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_operator","type":"address"},{"internalType":"address","name":"_sender","type":"address"},{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint64","name":"_chainId","type":"uint64"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"nonce","type":"uint64"}],"name":"AckEmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"nonce","type":"uint64"}],"name":"AckWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lpToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"mockPoolId","type":"uint256"}],"name":"AddedPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"pid","type":"uint256"}],"name":"AddedWhiteListPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"nonce","type":"uint64"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"nonce","type":"uint64"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"nonce","type":"uint64"}],"name":"FallbackDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"nonce","type":"uint64"}],"name":"FallbackWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newOperator","type":"address"},{"indexed":true,"internalType":"address","name":"oldOperator","type":"address"}],"name":"OperatorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"nonce","type":"uint64"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"BSC_CHAIN_ID","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CROSS_FARMING_RECEIVER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CROSS_FARMING_SENDER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_mcv2pid","type":"uint256"},{"internalType":"uint64","name":"_nonce","type":"uint64"}],"name":"ackEmergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_mcv2pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint64","name":"_nonce","type":"uint64"}],"name":"ackWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_lpToken","type":"address"},{"internalType":"uint256","name":"_mcv2PoolId","type":"uint256"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mcv2Pid","type":"uint256"}],"name":"addWhiteListPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"calcFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint64","name":"","type":"uint64"}],"name":"deposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"enum DataTypes.MessageTypes","name":"_msgType","type":"uint8"},{"internalType":"uint64","name":"_nonce","type":"uint64"}],"name":"encodeMessage","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint64","name":"_nonce","type":"uint64"}],"name":"fallbackDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint64","name":"_nonce","type":"uint64"}],"name":"fallbackWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"messageBus","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolInfo","outputs":[{"internalType":"contract IERC20","name":"lpToken","type":"address"},{"internalType":"uint256","name":"mcv2PoolId","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolMapping","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"}],"name":"setOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint64","name":"","type":"uint64"}],"name":"usedNonce","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"lastActionTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"whitelistPool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"}]