Address
0xcbd4424a0cb71825e7bb1d2fa563eefd0b4278ccCurrent Holdings
$0.00294000
TXs sent
0
First Active
2026-07-22
block 27,096,127
Last Active
3 days ago
block 27,540,383
Funded By
not identified
Net worth historyi
75 snapshots · to block 27,540,384coverage change 26 Augcoverage change 27 Augcoverage change 27 Augcoverage change 27 Augcoverage change 27 Aug
exact matchCallMeBabysolc 0.8.20+commit.a1b79de6runtime exact · creation exact
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/// ============================================================================
/// CallMeBaby
/// ----------------------------------------------------------------------------
/// Atomic two-pool flash-swap arbitrage between a "V1" and "V2" SHD/WPLS pair.
///
/// How it avoids needing pre-funded capital:
/// Uniswap-V2-style pairs let you call `swap()` and receive the output token
/// BEFORE paying anything, as long as you repay (in either token) before the
/// same transaction ends, and you pass non-empty `data` so the pair calls
/// your contract's `uniswapV2Call` callback mid-swap. This contract:
/// 1. Flash-borrows SHD from the cheaper pool (no payment yet).
/// 2. Sells that SHD into the more expensive pool for WPLS.
/// 3. Sends the WPLS needed to repay the flash-borrow back to the first pool.
/// 4. Keeps whatever WPLS is left as profit.
/// If steps 2-4 don't produce enough WPLS to repay + clear minProfitWPLS,
/// the whole transaction reverts. There is no partial-failure state — the
/// contract never needs to hold WPLS/SHD ahead of time.
///
/// Only `owner` (the deployer, transferrable) can trigger arbitrage or move
/// funds out of the contract.
/// ============================================================================
interface IERC20 {
function transfer(address to, uint256 value) external returns (bool);
function balanceOf(address account) external view returns (uint256);
}
interface IUniswapV2Pair {
function token0() external view returns (address);
function token1() external view returns (address);
function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external;
}
contract CallMeBaby {
// ===================== STATE =====================
address public owner;
bool public paused;
address public immutable WPLS;
address public immutable SHD;
address public immutable pairV1;
address public immutable pairV2;
// Fee numerators (denominator fixed at 1000). 997 = the common 0.3%-style
// Uniswap-V2 fee. VERIFY the real fee for V1 and V2 on-chain before relying
// on these defaults — if either pool actually charges a different fee, the
// repay/profit math here will be wrong and every call will simply revert
// (safe, but wastes gas) rather than silently mis-execute.
uint256 public feeNumV1 = 997;
uint256 public feeNumV2 = 997;
uint256 public constant FEE_DENOM = 1000;
// Optional safety cap on how much SHD a single call may flash-borrow.
// 0 = no cap.
uint256 public maxShdBorrowAmount;
bool private locked;
// ===================== EVENTS =====================
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
event PausedSet(bool paused);
event FeesUpdated(uint256 feeNumV1, uint256 feeNumV2);
event MaxBorrowUpdated(uint256 maxShdBorrowAmount);
event ArbExecuted(address indexed borrowPair, address indexed sellPair, uint256 shdBorrowed, uint256 profitWPLS);
event Withdrawn(address indexed token, address indexed to, uint256 amount);
// ===================== MODIFIERS =====================
modifier onlyOwner() {
require(msg.sender == owner, "not owner");
_;
}
modifier whenNotPaused() {
require(!paused, "paused");
_;
}
modifier nonReentrant() {
require(!locked, "reentrant");
locked = true;
_;
locked = false;
}
// ===================== CONSTRUCTOR =====================
constructor(address _wpls, address _shd, address _pairV1, address _pairV2) {
require(
_wpls != address(0) && _shd != address(0) && _pairV1 != address(0) && _pairV2 != address(0),
"zero addr"
);
owner = msg.sender;
WPLS = _wpls;
SHD = _shd;
pairV1 = _pairV1;
pairV2 = _pairV2;
emit OwnershipTransferred(address(0), msg.sender);
}
// ===================== OWNER ADMIN =====================
function transferOwnership(address newOwner) external onlyOwner {
require(newOwner != address(0), "zero addr");
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
function setPaused(bool _paused) external onlyOwner {
paused = _paused;
emit PausedSet(_paused);
}
function setFees(uint256 _feeNumV1, uint256 _feeNumV2) external onlyOwner {
require(_feeNumV1 <= FEE_DENOM && _feeNumV2 <= FEE_DENOM, "bad fee");
feeNumV1 = _feeNumV1;
feeNumV2 = _feeNumV2;
emit FeesUpdated(_feeNumV1, _feeNumV2);
}
function setMaxShdBorrowAmount(uint256 _max) external onlyOwner {
maxShdBorrowAmount = _max;
emit MaxBorrowUpdated(_max);
}
/// @notice Sweep any ERC20 sitting in this contract (accumulated profit, dust, etc.)
function withdrawToken(address token, uint256 amount, address to) external onlyOwner {
require(to != address(0), "zero addr");
require(IERC20(token).transfer(to, amount), "transfer failed");
emit Withdrawn(token, to, amount);
}
/// @notice Sweep any native PLS sitting in this contract.
function withdrawPLS(uint256 amount, address payable to) external onlyOwner {
require(to != address(0), "zero addr");
(bool ok, ) = to.call{value: amount}("");
require(ok, "PLS transfer failed");
emit Withdrawn(address(0), to, amount);
}
receive() external payable {}
// ===================== VIEW / MATH HELPERS =====================
function getReservesOrdered(address pair, address tokenA) public view returns (uint256 reserveA, uint256 reserveB) {
(uint112 r0, uint112 r1, ) = IUniswapV2Pair(pair).getReserves();
address token0 = IUniswapV2Pair(pair).token0();
if (token0 == tokenA) {
return (r0, r1);
} else {
return (r1, r0);
}
}
function getAmountOut(uint256 amountIn, uint256 reserveIn, uint256 reserveOut, uint256 feeNum)
public
pure
returns (uint256)
{
if (amountIn == 0 || reserveIn == 0 || reserveOut == 0) return 0;
uint256 amountInWithFee = amountIn * feeNum;
uint256 numerator = amountInWithFee * reserveOut;
uint256 denominator = reserveIn * FEE_DENOM + amountInWithFee;
return numerator / denominator;
}
function getAmountIn(uint256 amountOut, uint256 reserveIn, uint256 reserveOut, uint256 feeNum)
public
pure
returns (uint256)
{
require(amountOut < reserveOut, "insufficient liquidity");
uint256 numerator = reserveIn * amountOut * FEE_DENOM;
uint256 denominator = (reserveOut - amountOut) * feeNum;
return (numerator / denominator) + 1;
}
/// @notice Read-only preview of an arb size, so an off-chain bot can check
/// profitability before sending a transaction. executeArb() re-derives
/// and re-checks all of this on-chain anyway, so this is a convenience,
/// not a security boundary.
function quoteArb(bool buyOnV1, uint256 shdBorrowAmount)
external
view
returns (uint256 wplsOut, uint256 wplsRepay, int256 profit)
{
address borrowPair = buyOnV1 ? pairV1 : pairV2;
address sellPair = buyOnV1 ? pairV2 : pairV1;
uint256 feeBorrow = buyOnV1 ? feeNumV1 : feeNumV2;
uint256 feeSell = buyOnV1 ? feeNumV2 : feeNumV1;
(uint256 reserveSHDSell, uint256 reserveWPLSSell) = getReservesOrdered(sellPair, SHD);
wplsOut = getAmountOut(shdBorrowAmount, reserveSHDSell, reserveWPLSSell, feeSell);
(uint256 reserveSHDBorrow, uint256 reserveWPLSBorrow) = getReservesOrdered(borrowPair, SHD);
wplsRepay = getAmountIn(shdBorrowAmount, reserveWPLSBorrow, reserveSHDBorrow, feeBorrow);
profit = int256(wplsOut) - int256(wplsRepay);
}
// ===================== ARB EXECUTION =====================
/// @param buyOnV1 true = SHD is cheaper on V1: borrow SHD from V1, sell it on V2, repay V1 in WPLS.
/// false = SHD is cheaper on V2: borrow SHD from V2, sell it on V1, repay V2 in WPLS.
/// @param shdBorrowAmount how much SHD to flash-borrow from the cheap pool (sized off-chain,
/// e.g. by the same ternary-search optimizer used in arb.js).
/// @param minProfitWPLS revert unless net profit (in WPLS, before gas) is at least this much.
function executeArb(bool buyOnV1, uint256 shdBorrowAmount, uint256 minProfitWPLS)
external
onlyOwner
whenNotPaused
nonReentrant
{
require(shdBorrowAmount > 0, "zero amount");
if (maxShdBorrowAmount > 0) {
require(shdBorrowAmount <= maxShdBorrowAmount, "exceeds max borrow");
}
address borrowPair = buyOnV1 ? pairV1 : pairV2;
address token0 = IUniswapV2Pair(borrowPair).token0();
uint256 amount0Out = token0 == SHD ? shdBorrowAmount : 0;
uint256 amount1Out = token0 == SHD ? 0 : shdBorrowAmount;
// Non-empty data is what makes this a flash swap: the pair will call
// uniswapV2Call on `to` (this contract) before checking repayment.
bytes memory data = abi.encode(buyOnV1, minProfitWPLS);
IUniswapV2Pair(borrowPair).swap(amount0Out, amount1Out, address(this), data);
}
/// @dev Uniswap-V2-style flash swap callback. Called by pairV1 or pairV2 mid-`swap()`,
/// never called directly by us.
function uniswapV2Call(address sender, uint256 amount0, uint256 amount1, bytes calldata data) external {
// Only one of our two known pairs may call this...
require(msg.sender == pairV1 || msg.sender == pairV2, "unknown pair");
// ...and only as a result of a swap *we* initiated (blocks a third party from
// calling pair.swap(..., to: thisContract, ...) themselves to spoof this callback).
require(sender == address(this), "not our flash swap");
(bool buyOnV1, uint256 minProfitWPLS) = abi.decode(data, (bool, uint256));
address borrowPair = msg.sender;
address sellPair = buyOnV1 ? pairV2 : pairV1;
uint256 feeBorrow = buyOnV1 ? feeNumV1 : feeNumV2;
uint256 feeSell = buyOnV1 ? feeNumV2 : feeNumV1;
uint256 shdReceived = amount0 > 0 ? amount0 : amount1;
require(shdReceived > 0, "nothing borrowed");
// ---- Leg 2: sell the borrowed SHD on the other pool for WPLS ----
require(IERC20(SHD).transfer(sellPair, shdReceived), "transfer to sellPair failed");
(uint256 reserveSHDSell, uint256 reserveWPLSSell) = getReservesOrdered(sellPair, SHD);
uint256 wplsOut = getAmountOut(shdReceived, reserveSHDSell, reserveWPLSSell, feeSell);
require(wplsOut > 0, "sell leg produced nothing");
address sellToken0 = IUniswapV2Pair(sellPair).token0();
uint256 s0Out = sellToken0 == WPLS ? wplsOut : 0;
uint256 s1Out = sellToken0 == WPLS ? 0 : wplsOut;
IUniswapV2Pair(sellPair).swap(s0Out, s1Out, address(this), ""); // empty data = plain swap, no callback
// ---- Figure out what we owe the borrow pool to repay the flash swap ----
(uint256 reserveSHDBorrow, uint256 reserveWPLSBorrow) = getReservesOrdered(borrowPair, SHD);
uint256 wplsRepay = getAmountIn(shdReceived, reserveWPLSBorrow, reserveSHDBorrow, feeBorrow);
require(wplsOut > wplsRepay, "unprofitable");
uint256 profit = wplsOut - wplsRepay;
require(profit >= minProfitWPLS, "profit below minimum");
require(IERC20(WPLS).transfer(borrowPair, wplsRepay), "repay transfer failed");
// Profit is left sitting in this contract in WPLS; withdraw anytime via withdrawToken().
emit ArbExecuted(borrowPair, sellPair, shdReceived, profit);
}
}