Summary
schedule_payout creates a ScheduledPayout record and updates PublisherEarnings.pending_amount, but it does NOT transfer any tokens into the contract. execute_payout later calls token_client.transfer(&env.current_contract_address(), &payout.recipient, &payout.amount), requiring the contract to hold the tokens. There is no fund_contract or deposit function in payout-automation. Tokens must be sent directly to the contract address by an off-chain process with no on-chain enforcement.
Impact
An admin can schedule arbitrarily large payouts (limited only by MaxPendingAmount) with nothing locking the corresponding tokens. When execute_payout is called, it panics if the contract has insufficient balance — permanent blocking for a correctly-scheduled payout. Recipients cannot reliably know if their payout will execute.
Fix
Add a fund_payouts(sender, amount) function that pulls tokens into the contract:
pub fn fund_payouts(env: Env, sender: Address, amount: i128) {
sender.require_auth();
let token: Address = env.storage().instance().get(&DataKey::TokenAddress).unwrap();
token::Client::new(&env, &token).transfer(&sender, &env.current_contract_address(), &amount);
}
Summary
schedule_payoutcreates aScheduledPayoutrecord and updatesPublisherEarnings.pending_amount, but it does NOT transfer any tokens into the contract.execute_payoutlater callstoken_client.transfer(&env.current_contract_address(), &payout.recipient, &payout.amount), requiring the contract to hold the tokens. There is nofund_contractordepositfunction inpayout-automation. Tokens must be sent directly to the contract address by an off-chain process with no on-chain enforcement.Impact
An admin can schedule arbitrarily large payouts (limited only by
MaxPendingAmount) with nothing locking the corresponding tokens. Whenexecute_payoutis called, it panics if the contract has insufficient balance — permanent blocking for a correctly-scheduled payout. Recipients cannot reliably know if their payout will execute.Fix
Add a
fund_payouts(sender, amount)function that pulls tokens into the contract: