Address
0x7ee5476ae357b02f3f61ba0d8369945d3615e0deCurrent Holdings
$0.00
TXs sent
not counted
First Active
2025-11-16
block 25,032,007
Last Active
54 days ago
block 27,099,831
Net worth historyi
115 snapshots · to block 27,530,895coverage change 26 Augcoverage change 27 Augcoverage change 27 Augcoverage change 27 Augcoverage change 27 Aug
exact matchDivineManagersolc 0.8.24+commit.e11b9ed9runtime exact · creation exact
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/**
* @title DivineManager
* @notice On-chain executor for HolyC / JIT arbitrage tickets generated by the off-chain scanner.
* The contract is designed for PulseChain (PLS/WPLS) and follows the execution guidelines
* captured in `ContractDesign.md`. It keeps strict guard-rails, tracks vault balances, and
* settles profits with optional splits and caller gas top-ups.
*/
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, 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 sender, address recipient, uint256 amount) external returns (bool);
function decimals() external view returns (uint8);
}
interface IWPLS is IERC20 {
function deposit() external payable;
function withdraw(uint256) external;
}
interface IJustInTimeCompiler {
function compile(uint256 amount) external;
function restore(uint256 amount) external;
}
interface IUniswapV2Router02 {
function factory() external view returns (address);
function WETH() external view returns (address);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external;
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts);
function getAmountsIn(uint256 amountOut, address[] calldata path) external view returns (uint256[] memory amounts);
}
interface IUniswapV2Pair {
function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
}
library SafeERC20 {
function safeTransfer(IERC20 token, address to, uint256 value) internal {
require(_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)), "TRANSFER_FAIL");
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
require(_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)), "TRANSFER_FROM_FAIL");
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
require(_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)), "APPROVE_FAIL");
}
function _callOptionalReturn(IERC20 token, bytes memory data) private returns (bool) {
(bool success, bytes memory returndata) = address(token).call(data);
if (!success) return false;
if (returndata.length == 0) return true;
return abi.decode(returndata, (bool));
}
}
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, "REENTRANCY");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
contract DivineManager is ReentrancyGuard {
using SafeERC20 for IERC20;
uint256 private constant BPS = 10_000;
uint256 private constant MAX_SPLIT_BPS = 9_000; // 90%
uint256 public constant CALLER_TOP_OFF_THRESHOLD = 500_000 ether; // 500k PLS
address public constant BURN_ADDRESS = 0x0000000000000000000000000000000000000369;
enum Asset {
HC,
JIT,
WPLS
}
enum LegKey {
COMPILE,
RESTORE,
SWAP_SUPPORTING_FOT,
SWAP_EXACT
}
struct BurnInstruction {
uint256 owedHolyC;
uint256 owedJIT;
}
struct TicketLeg {
LegKey key;
address[] path; // optional for compile/restore
uint256 amountIn;
uint256 amountOutMin;
}
struct FinalGuard {
Asset asset;
uint256 minAmount;
}
struct BindingPair {
address pair;
uint256 reserve0;
uint256 reserve1;
}
struct BindingData {
uint256 blockNumberObserved;
BindingPair[] pairs;
uint16 reservesToleranceBps;
bytes32 policyHash;
}
struct ExecutionTicket {
bytes32 strategyId;
Asset targetAsset;
uint256 minProfitWPLS;
uint256 deadline;
uint256 basefeeCap;
bytes32 policyHash;
TicketLeg[] legs;
FinalGuard finalGuard;
BindingData binding;
BurnInstruction burn;
bytes32 jobNonce;
}
struct Policy {
uint256 minProfitWPLS;
uint256 basefeeCap;
uint16 safetyBpsPerLeg;
uint16 reservesToleranceBps;
uint32 deadlineSeconds;
bool executorTaxExempt;
bool burnAfterEnabled;
bool denyJitSells;
bytes32 hash;
}
struct VaultSnapshot {
uint256 native;
uint256 holyC;
uint256 jit;
uint256 wpls;
}
address public owner;
address public pendingOwner;
address public immutable HOLYC;
address public immutable JIT;
address public immutable WPLS;
IJustInTimeCompiler public immutable compiler;
IWPLS private immutable wplsWrapper;
IUniswapV2Router02 public router;
address public botCaller;
bool public splitEnabled;
uint16 public splitBps;
address public splitDestination;
Policy public policy;
mapping(bytes32 => bool) public jobNonceConsumed;
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
event BotCallerUpdated(address indexed caller);
event SplitConfigurationUpdated(bool enabled, uint16 splitBps, address indexed destination);
event PolicyUpdated(bytes32 indexed policyHash, Policy policy);
event RouterUpdated(address indexed previousRouter, address indexed newRouter);
event TopOffExecuted(address indexed caller, uint256 nativeAmount, uint256 wplsUsed);
event SplitPaid(
address indexed destination,
uint256 wplsAmount,
uint256 holyCAmount,
uint256 jitAmount
);
event TicketExecuted(bytes32 indexed strategyId, bytes32 indexed jobNonce, uint256 profitWPLS);
modifier onlyOwner() {
require(msg.sender == owner, "NOT_OWNER");
_;
}
modifier onlyExecutor() {
require(msg.sender == botCaller || msg.sender == owner, "NOT_EXECUTOR");
_;
}
constructor(
address owner_,
address botCaller_,
address holyc_,
address jit_,
address wpls_,
address compiler_,
address router_
) {
require(owner_ != address(0), "OWNER_ZERO");
require(holyc_ != address(0) && jit_ != address(0) && wpls_ != address(0), "TOKEN_ZERO");
require(compiler_ != address(0) && router_ != address(0), "CONFIG_ZERO");
owner = owner_;
botCaller = botCaller_;
HOLYC = holyc_;
JIT = jit_;
WPLS = wpls_;
compiler = IJustInTimeCompiler(compiler_);
router = IUniswapV2Router02(router_);
wplsWrapper = IWPLS(wpls_);
_setAllowances(router_);
}
// ----------------------------
// Owner functions
// ----------------------------
function transferOwnership(address newOwner) external onlyOwner {
require(newOwner != address(0), "OWNER_ZERO");
pendingOwner = newOwner;
emit OwnershipTransferStarted(owner, newOwner);
}
function acceptOwnership() external {
require(msg.sender == pendingOwner, "NOT_PENDING");
address previous = owner;
owner = pendingOwner;
pendingOwner = address(0);
emit OwnershipTransferred(previous, owner);
}
function setBotCaller(address caller) external onlyOwner {
botCaller = caller;
emit BotCallerUpdated(caller);
}
function setSplitConfiguration(bool enabled, uint16 splitBps_, address destination) external onlyOwner {
require(!enabled || (destination != address(0) && splitBps_ <= MAX_SPLIT_BPS), "INVALID_SPLIT");
splitEnabled = enabled;
splitBps = splitBps_;
splitDestination = destination;
emit SplitConfigurationUpdated(enabled, splitBps_, destination);
}
function setRouter(address newRouter) external onlyOwner {
require(newRouter != address(0), "ROUTER_ZERO");
address previous = address(router);
if (previous != address(0)) {
IERC20(HOLYC).safeApprove(previous, 0);
IERC20(JIT).safeApprove(previous, 0);
IERC20(WPLS).safeApprove(previous, 0);
}
router = IUniswapV2Router02(newRouter);
_setAllowances(newRouter);
emit RouterUpdated(previous, newRouter);
}
function setPolicy(Policy calldata policy_) external onlyOwner {
Policy memory newPolicy = policy_;
newPolicy.hash = _computePolicyHash(policy_);
policy = newPolicy;
emit PolicyUpdated(newPolicy.hash, newPolicy);
}
// Emergency withdrawal (owner only)
function withdrawToken(address token, uint256 amount, address to) external onlyOwner {
require(to != address(0), "WITHDRAW_ZERO");
IERC20(token).safeTransfer(to, amount);
}
function withdrawNative(uint256 amount, address payable to) external onlyOwner {
require(to != address(0), "WITHDRAW_ZERO");
(bool ok, ) = to.call{value: amount}("");
require(ok, "NATIVE_WITHDRAW_FAIL");
}
// ----------------------------
// Execution API
// ----------------------------
function execute(bytes calldata payload) external nonReentrant onlyExecutor {
require(policy.hash != bytes32(0), "POLICY_UNSET");
ExecutionTicket memory ticket = abi.decode(payload, (ExecutionTicket));
require(ticket.deadline >= block.timestamp, "DEADLINE_PASSED");
require(ticket.policyHash == policy.hash, "POLICY_MISMATCH");
if (ticket.basefeeCap > 0 || policy.basefeeCap > 0) {
uint256 cap = ticket.basefeeCap > 0 ? ticket.basefeeCap : policy.basefeeCap;
require(block.basefee <= cap, "BASEFEE_HIGH");
}
require(!jobNonceConsumed[ticket.jobNonce], "NONCE_USED");
jobNonceConsumed[ticket.jobNonce] = true;
_validateBinding(ticket.binding);
VaultSnapshot memory beforeSnap = _snapshotVault();
_executeLegs(ticket.legs, ticket.deadline);
if (policy.executorTaxExempt && policy.burnAfterEnabled) {
_settleBurn(ticket.burn);
} else {
require(ticket.burn.owedHolyC == 0 && ticket.burn.owedJIT == 0, "BURN_UNEXPECTED");
}
VaultSnapshot memory afterSnap = _snapshotVault();
uint256 profitWPLS = _validateProfit(ticket, beforeSnap, afterSnap);
// Optional split
uint256 remainingProfit = profitWPLS;
uint256 holyCProfit = 0;
if (afterSnap.holyC > beforeSnap.holyC) {
holyCProfit = afterSnap.holyC - beforeSnap.holyC;
}
uint256 jitProfit = 0;
if (afterSnap.jit > beforeSnap.jit) {
jitProfit = afterSnap.jit - beforeSnap.jit;
}
uint256 sentWPLS = 0;
uint256 sentHolyC = 0;
uint256 sentJIT = 0;
if (splitEnabled && splitDestination != address(0) && splitBps > 0) {
uint256 splitAmount = (profitWPLS * splitBps) / BPS;
if (splitAmount > 0) {
_distributeWPLS(splitDestination, splitAmount);
sentWPLS = splitAmount;
remainingProfit -= splitAmount;
}
if (holyCProfit > 0) {
uint256 splitHolyC = (holyCProfit * splitBps) / BPS;
if (splitHolyC > 0) {
IERC20(HOLYC).safeTransfer(splitDestination, splitHolyC);
sentHolyC = splitHolyC;
}
}
if (jitProfit > 0) {
uint256 splitJIT = (jitProfit * splitBps) / BPS;
if (splitJIT > 0) {
IERC20(JIT).safeTransfer(splitDestination, splitJIT);
sentJIT = splitJIT;
}
}
if (sentWPLS > 0 || sentHolyC > 0 || sentJIT > 0) {
emit SplitPaid(splitDestination, sentWPLS, sentHolyC, sentJIT);
}
}
// Caller top-off
if (botCaller != address(0)) {
uint256 spent = _topOffCaller(remainingProfit, ticket.deadline);
if (spent > remainingProfit) {
remainingProfit = 0;
} else {
remainingProfit -= spent;
}
}
VaultSnapshot memory finalSnap = _snapshotVault();
uint256 beforeWPLSValue = beforeSnap.wpls + beforeSnap.native;
uint256 finalWPLSValue = finalSnap.wpls + finalSnap.native;
// Sanity: even after split + top-off, vault WPLS+PLS didn't go below start-of-tx.
// HC/JIT movement is governed by the off-chain scanner + ticket.finalGuard.
require(finalWPLSValue >= beforeWPLSValue, "FINAL_WPLS_NEGATIVE");
emit TicketExecuted(ticket.strategyId, ticket.jobNonce, profitWPLS);
}
// ----------------------------
// Internal helpers
// ----------------------------
function _executeLegs(TicketLeg[] memory legs, uint256 txDeadline) internal {
uint256 len = legs.length;
require(len > 0, "NO_LEGS");
for (uint256 i = 0; i < len; ++i) {
TicketLeg memory leg = legs[i];
if (policy.denyJitSells && _isJitSell(leg)) {
revert("JIT_SELL_DENIED");
}
if (leg.key == LegKey.COMPILE) {
_executeCompile(leg.amountIn, leg.amountOutMin);
} else if (leg.key == LegKey.RESTORE) {
_executeRestore(leg.amountIn, leg.amountOutMin);
} else {
require(leg.path.length >= 2, "PATH_SHORT");
if (leg.key == LegKey.SWAP_SUPPORTING_FOT) {
_executeSwapSupportingFOT(leg.path, leg.amountIn, leg.amountOutMin, txDeadline);
} else if (leg.key == LegKey.SWAP_EXACT) {
_executeSwapExact(leg.path, leg.amountIn, leg.amountOutMin, txDeadline);
} else {
revert("LEG_UNKNOWN");
}
}
}
}
function _isJitSell(TicketLeg memory leg) internal view returns (bool) {
if (leg.key == LegKey.COMPILE || leg.path.length == 0) return false;
return leg.path[0] == JIT;
}
function _executeCompile(uint256 amountIn, uint256 minOut) internal {
require(amountIn > 0, "COMPILE_ZERO");
IERC20 holyC = IERC20(HOLYC);
require(holyC.balanceOf(address(this)) >= amountIn, "HC_BAL_LOW");
uint256 beforeBal = IERC20(JIT).balanceOf(address(this));
compiler.compile(amountIn);
uint256 delta = IERC20(JIT).balanceOf(address(this)) - beforeBal;
require(delta >= minOut, "COMPILE_MIN");
}
function _executeRestore(uint256 amountIn, uint256 minOut) internal {
require(amountIn > 0, "RESTORE_ZERO");
IERC20 holyC = IERC20(HOLYC);
IERC20 jit = IERC20(JIT);
require(jit.balanceOf(address(this)) >= amountIn, "JIT_BAL_LOW");
uint256 beforeBal = holyC.balanceOf(address(this));
compiler.restore(amountIn);
uint256 afterBal = holyC.balanceOf(address(this));
require(afterBal - beforeBal >= minOut, "RESTORE_MIN");
}
function _executeSwapSupportingFOT(
address[] memory path,
uint256 amountIn,
uint256 minOut,
uint256 txDeadline
) internal {
require(IERC20(path[0]).balanceOf(address(this)) >= amountIn, "SWAP_BAL_LOW");
uint256 beforeBal = IERC20(path[path.length - 1]).balanceOf(address(this));
router.swapExactTokensForTokensSupportingFeeOnTransferTokens(
amountIn,
minOut,
path,
address(this),
txDeadline
);
uint256 delta = IERC20(path[path.length - 1]).balanceOf(address(this)) - beforeBal;
require(delta >= minOut, "SWAP_FOT_MIN");
}
function _executeSwapExact(
address[] memory path,
uint256 amountIn,
uint256 minOut,
uint256 txDeadline
) internal {
require(IERC20(path[0]).balanceOf(address(this)) >= amountIn, "SWAP_BAL_LOW");
uint256 beforeBal = IERC20(path[path.length - 1]).balanceOf(address(this));
router.swapExactTokensForTokens(amountIn, minOut, path, address(this), txDeadline);
uint256 delta = IERC20(path[path.length - 1]).balanceOf(address(this)) - beforeBal;
require(delta >= minOut, "SWAP_MIN");
}
function _settleBurn(BurnInstruction memory burn) internal {
if (burn.owedHolyC == 0 && burn.owedJIT == 0) return;
uint256 totalHolyC = burn.owedHolyC;
if (burn.owedJIT > 0) {
IERC20 jit = IERC20(JIT);
require(jit.balanceOf(address(this)) >= burn.owedJIT, "BURN_JIT_BAL");
uint256 beforeHC = IERC20(HOLYC).balanceOf(address(this));
compiler.restore(burn.owedJIT);
uint256 restored = IERC20(HOLYC).balanceOf(address(this)) - beforeHC;
totalHolyC += restored;
}
if (totalHolyC > 0) {
IERC20(HOLYC).safeTransfer(BURN_ADDRESS, totalHolyC);
}
}
function _validateBinding(BindingData memory binding) internal view {
require(binding.policyHash == policy.hash, "BIND_POLICY");
if (binding.blockNumberObserved == 0) return; // optional binding
require(block.number >= binding.blockNumberObserved, "BLOCK_PAST");
uint256 len = binding.pairs.length;
uint16 tolerance = binding.reservesToleranceBps > 0 ? binding.reservesToleranceBps : policy.reservesToleranceBps;
for (uint256 i = 0; i < len; ++i) {
BindingPair memory snap = binding.pairs[i];
(uint112 reserve0, uint112 reserve1, ) = IUniswapV2Pair(snap.pair).getReserves();
_requireWithinTolerance(reserve0, snap.reserve0, tolerance);
_requireWithinTolerance(reserve1, snap.reserve1, tolerance);
}
}
function _requireWithinTolerance(uint256 liveValue, uint256 snapValue, uint16 toleranceBps) internal pure {
if (snapValue == 0) return;
uint256 diff = liveValue > snapValue ? liveValue - snapValue : snapValue - liveValue;
require(diff * BPS <= snapValue * toleranceBps, "RESERVE_DRIFT");
}
function _snapshotVault() internal view returns (VaultSnapshot memory snap) {
snap.native = address(this).balance;
snap.holyC = IERC20(HOLYC).balanceOf(address(this));
snap.jit = IERC20(JIT).balanceOf(address(this));
snap.wpls = IERC20(WPLS).balanceOf(address(this));
}
function _validateProfit(
ExecutionTicket memory ticket,
VaultSnapshot memory beforeSnap,
VaultSnapshot memory afterSnap
) internal view returns (uint256 profitWPLS) {
uint256 beforeWPLSValue = beforeSnap.wpls + beforeSnap.native;
uint256 afterWPLSValue = afterSnap.wpls + afterSnap.native;
require(afterWPLSValue >= beforeWPLSValue, "WPLS_NEGATIVE");
profitWPLS = afterWPLSValue - beforeWPLSValue;
require(profitWPLS >= ticket.minProfitWPLS && profitWPLS >= policy.minProfitWPLS, "MIN_PROFIT_FAIL");
if (ticket.finalGuard.asset == Asset.HC) {
require(afterSnap.holyC >= beforeSnap.holyC + ticket.finalGuard.minAmount, "HC_GUARD");
} else if (ticket.finalGuard.asset == Asset.JIT) {
require(afterSnap.jit >= beforeSnap.jit + ticket.finalGuard.minAmount, "JIT_GUARD");
} else if (ticket.finalGuard.asset == Asset.WPLS) {
require(afterWPLSValue >= beforeWPLSValue + ticket.finalGuard.minAmount, "WPLS_GUARD");
}
}
function _distributeWPLS(address destination, uint256 amount) internal {
uint256 nativeBal = address(this).balance;
if (nativeBal < amount) {
uint256 shortage = amount - nativeBal;
uint256 wplsBal = IERC20(WPLS).balanceOf(address(this));
require(wplsBal >= shortage, "SPLIT_FUNDS");
wplsWrapper.withdraw(shortage);
}
(bool ok, ) = payable(destination).call{value: amount}("");
require(ok, "SPLIT_NATIVE_FAIL");
}
function _topOffCaller(uint256 maxSpendWPLS, uint256 txDeadline) internal returns (uint256 spent) {
address target = botCaller;
if (target == address(0)) return 0;
uint256 balance = target.balance;
if (balance >= CALLER_TOP_OFF_THRESHOLD) return 0;
uint256 deficit = CALLER_TOP_OFF_THRESHOLD - balance;
if (deficit == 0) return 0;
if (maxSpendWPLS < deficit) {
return 0;
}
uint256 nativeBal = address(this).balance;
uint256 remaining = deficit;
uint256 wplsUsed = 0;
if (nativeBal >= remaining) {
(bool ok, ) = payable(target).call{value: remaining}("");
require(ok, "TOP_OFF_NATIVE_FAIL");
emit TopOffExecuted(target, remaining, 0);
return remaining;
}
// Use all native first
if (nativeBal > 0) {
(bool ok2, ) = payable(target).call{value: nativeBal}("");
require(ok2, "TOP_OFF_NATIVE_FAIL");
remaining -= nativeBal;
spent += nativeBal;
}
uint256 wplsBal = IERC20(WPLS).balanceOf(address(this));
if (wplsBal >= remaining) {
wplsWrapper.withdraw(remaining);
wplsUsed += remaining;
(bool ok3, ) = payable(target).call{value: remaining}("");
require(ok3, "TOP_OFF_NATIVE_FAIL");
spent += remaining;
emit TopOffExecuted(target, deficit, wplsUsed);
return spent;
}
// Need to convert HolyC -> WPLS for the residual amount.
if (wplsBal > 0) {
wplsWrapper.withdraw(wplsBal);
(bool ok4, ) = payable(target).call{value: wplsBal}("");
require(ok4, "TOP_OFF_NATIVE_FAIL");
spent += wplsBal;
remaining -= wplsBal;
wplsUsed += wplsBal;
}
_swapHolyCForWPLSTopOff(remaining, txDeadline);
wplsWrapper.withdraw(remaining);
(bool ok5, ) = payable(target).call{value: remaining}("");
require(ok5, "TOP_OFF_NATIVE_FAIL");
spent = deficit;
wplsUsed += remaining;
emit TopOffExecuted(target, deficit, wplsUsed);
}
function _swapHolyCForWPLSTopOff(uint256 amountOut, uint256 txDeadline) internal {
// Sell HOLYC to source the exact WPLS amount needed for gas top-off.
address[] memory path = new address[](2);
path[0] = HOLYC;
path[1] = WPLS;
uint256 amountHC = router.getAmountsIn(amountOut, path)[0];
require(IERC20(HOLYC).balanceOf(address(this)) >= amountHC, "HC_TOP_OFF");
uint256 before = IERC20(WPLS).balanceOf(address(this));
router.swapExactTokensForTokens(amountHC, amountOut, path, address(this), txDeadline);
require(IERC20(WPLS).balanceOf(address(this)) - before >= amountOut, "TOP_OFF_MIN_OUT");
}
function _computePolicyHash(Policy calldata p) internal pure returns (bytes32) {
return keccak256(
abi.encode(
p.minProfitWPLS,
p.basefeeCap,
p.safetyBpsPerLeg,
p.reservesToleranceBps,
p.deadlineSeconds,
p.executorTaxExempt,
p.burnAfterEnabled,
p.denyJitSells
)
);
}
function _setAllowances(address router_) internal {
IERC20(HOLYC).safeApprove(router_, 0);
IERC20(JIT).safeApprove(router_, 0);
IERC20(WPLS).safeApprove(router_, 0);
IERC20(HOLYC).safeApprove(address(compiler), 0);
IERC20(JIT).safeApprove(address(compiler), 0);
IERC20(HOLYC).safeApprove(router_, type(uint256).max);
IERC20(JIT).safeApprove(router_, type(uint256).max);
IERC20(WPLS).safeApprove(router_, type(uint256).max);
IERC20(HOLYC).safeApprove(address(compiler), type(uint256).max);
IERC20(JIT).safeApprove(address(compiler), type(uint256).max);
}
// Allow the contract to receive native PLS
receive() external payable {}
}