Description:
Decentralized Finance (DeFi) protocol contract providing Factory functionality.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"tru3x.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/// ---- Minimal ERC20 ----
interface IERC20 {
function approve(address spender, uint256 value) external returns (bool);
function transfer(address to, uint256 value) external returns (bool);
function balanceOf(address account) external view returns (uint256);
}
/// ---- Uniswap V3 Router (ExactInputSingle) ----
interface ISwapRouter {
struct ExactInputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 deadline;
uint256 amountIn;
uint256 amountOutMinimum;
uint160 sqrtPriceLimitX96; // set 0 for no limit
}
function exactInputSingle(ExactInputSingleParams calldata params)
external
payable
returns (uint256 amountOut);
}
/**
* @title TruthTimedSellerV3
* @notice Sells a fixed amount of TRUU for a chosen stable (USDC/USDT) via Uniswap V3.
* - No arrays (avoids the address issue entirely)
* - Cooldown enforces 1 run per interval (e.g., every 3 hours)
* - Owner/keeper can trigger `execute(minOut)`
* - Constructor grants router infinite TRUU approval (one-time)
* - Supports pause, sweep, and on-chain reconfiguration if ever needed (no code edits)
*/
contract TruthTimedSellerV3 {
// ---- roles ----
address public owner;
address public keeper;
bool public paused;
// ---- tokens & router ----
IERC20 public immutable TRUU;
IERC20 public immutable STABLE;
ISwapRouter public constant ROUTER = ISwapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564); // Uniswap V3 router
// ---- config ----
uint256 public sellAmount; // TRUU amount in smallest units (TRUU has 10 decimals)
uint24 public poolFee; // e.g., 3000 for 0.3%, 10000 for 1.0%, 500 for 0.05%
uint256 public interval; // seconds between runs (e.g., 3 hours = 10800)
// ---- state ----
uint256 public lastExec;
// ---- simple nonReentrant guard ----
uint256 private _locked;
modifier nonReentrant() {
require(_locked == 0, "reentrancy");
_locked = 1;
_;
_locked = 0;
}
modifier onlyOwner() { require(msg.sender == owner, "not owner"); _; }
modifier onlyKeeperOrOwner() { require(msg.sender == keeper || msg.sender == owner, "not keeper/owner"); _; }
modifier notPaused() { require(!paused, "paused"); _; }
// ---- events ----
event Executed(uint256 truuIn, uint256 stableOut, uint256 when);
event KeeperSet(address keeper);
event IntervalSet(uint256 secondsInterval);
event SellAmountSet(uint256 amount);
event PoolFeeSet(uint24 fee);
event Paused(bool isPaused);
/**
* @param _truu TRUU token address (ERC20)
* @param _stable Target stable (USDC or USDT) address (ERC20)
* @param _keeper Address allowed to call execute in addition to owner
* @param _sellAmt Fixed TRUU amount per run (include TRUU's 10 decimals)
* @param _poolFee Uniswap V3 pool fee (e.g., 3000 = 0.3%)
* @param _interval Cooldown in seconds (e.g., 10800 for 3 hours)
*/
constructor(
address _truu,
address _stable,
address _keeper,
uint256 _sellAmt,
uint24 _poolFee,
uint256 _interval
) {
owner = msg.sender;
keeper = _keeper;
TRUU = IERC20(_truu);
STABLE = IERC20(_stable);
sellAmount= _sellAmt;
poolFee = _poolFee;
interval = _interval;
// One-time infinite approval so router can pull TRUU from this contract
require(TRUU.approve(address(ROUTER), type(uint256).max), "approve fail");
}
// ---- admin (no code edits needed later; all on-chain) ----
function setKeeper(address k) external onlyOwner { keeper = k; emit KeeperSet(k); }
function setPaused(bool p) external onlyOwner { paused = p; emit Paused(p); }
function setSellAmount(uint256 amt) external onlyOwner { sellAmount = amt; emit SellAmountSet(amt); }
function setInterval(uint256 s) external onlyOwner { require(s >= 600, "min 10m"); interval = s; emit IntervalSet(s); }
function setPoolFee(uint24 f) external onlyOwner { poolFee = f; emit PoolFeeSet(f); }
function sweep(address token, uint256 amount, address to) external onlyOwner {
IERC20(token).transfer(to, amount);
}
/// @notice Execute one sell. Pass a conservative minOut (in STABLE units) or 0 to accept router quote.
function execute(uint256 minOut) external onlyKeeperOrOwner notPaused nonReentrant {
require(block.timestamp >= lastExec + interval, "cooldown");
require(sellAmount > 0, "sellAmount=0");
require(TRUU.balanceOf(address(this)) >= sellAmount, "insufficient TRUU");
uint256 beforeBal = STABLE.balanceOf(address(this));
ISwapRouter.ExactInputSingleParams memory p = ISwapRouter.ExactInputSingleParams({
tokenIn: address(TRUU),
tokenOut: address(STABLE),
fee: poolFee,
recipient: address(this), // receive here; transfer to owner below
deadline: block.timestamp + 300, // 5 min to cut MEV/stale risk
amountIn: sellAmount,
amountOutMinimum: minOut, // set >0 if you want protection, else 0
sqrtPriceLimitX96: 0 // no price limit
});
uint256 outAmt = ROUTER.exactInputSingle(p);
// Safety: if minOut==0 we still assert we got >0
require(outAmt > 0, "no output");
uint256 gained = STABLE.balanceOf(address(this)) - beforeBal;
// send proceeds to owner
if (gained > 0) {
STABLE.transfer(owner, gained);
}
lastExec = block.timestamp;
emit Executed(sellAmount, gained, lastExec);
}
// allow receiving ETH (not expected for stable routes, but harmless)
receive() external payable {}
}"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"remappings": []
}
}}
Submitted on: 2025-11-07 10:38:29
Comments
Log in to comment.
No comments yet.