Skip to main content
The program reads Chainlink’s ETH/USD feed and computes how far the price has moved from reference, as a signed number of basis points. When the change is at or below dipBps, a negative threshold such as -300, it spends tranche of the Pot’s USDC on WETH in Uniswap V3’s 0.05% pool, under a price limit. Otherwise it buys nothing and returns normally. The cook reverts on a stale or non-positive feed answer, a positive dipBps, or an average price paid above priceLimit. Target chains: Ethereum. Chainlink.EthUsdFeed is not in Base’s registry, and sauce compile --chain base refuses the file. This program evaluates conditions only when called. To run it repeatedly, use an external scheduler or caller that submits an authorized transaction.

Prerequisites

Install the Sauce CLI to compile and simulate. To send the transaction, configure a wallet with native coin for gas and the Kitchen fee. Fund the Pot once it is deployed, or use --fund; it needs at least tranche USDC when the program buys.

Program

pot is the Pot the program runs on, available without declaring it; pot.USDC and pot.WETH are its balances (Names).
buy-the-dip.sauce.ts

How it works

  • change is an Int256 because the price can sit above or below reference. round.answer is already Int256, since Chainlink declares it int256. Int256(reference) converts the unsigned parameter with a check: a value above 2²⁵⁵ − 1 reverts. The subtraction, multiplication and division are then signed, and the division truncates toward zero.
  • Mixing the two kinds does not compile. round.answer - reference without the conversion is rejected with “cannot combine Int256 and Uint256 in this expression; convert an operand with Int256(value) or Uint256(value) first (conversions check bounds)”.
  • dipBps is an Int256 parameter, so it can be negative. A negative literal is an Int256; negating a nonzero Uint256 (-amount) fails, so a signed negative from an unsigned value is written -Int256(amount).
  • The swap half is the same as in Dollar-cost averaging: the price limit stops the pool at priceLimit, and spent and bought are the Pot’s balance changes, checked against priceLimit after the swap.

Run the example

1

Compile

2

Simulate

--assume-balance USDC:250 gives the Pot 250 USDC for this simulation only. --args reads -300 as a negative integer for the Int256 parameter.
3

Send

sauce tx buy-the-dip.sauce.ts --chain ethereum --owner <your-address> --args 250000000000 -300 3600 250000000 2500000000 prints the unsigned transactions instead, for your own signer or scheduler.

Simulation result

Simulated on a local fork of Ethereum at block 26284400 with the current contracts, using the Simulate command above: a reference of 2,500 USD, above the market. Nothing was signed or sent.
The feed answered 2,324.91817030 USD, 7.0033% below the reference. The division truncates that to change: -700, which is at or below -300, so the program spent 250 USDC for 0.10723065971750959 WETH, an average of about 2,331.42 USDC per WETH with the fee included. On the same fork, with a reference of 2,300 USD, below the market, the change is positive and nothing is bought:
A positive dipBps is refused:

Next steps