Keepers profitability


I’ve been runing a Keeper for several hours now. First, I must say that is an awesome creation. Thank you @andre.cronje !

Nonetheless, It is currently quite complicated to run a profitable keeper because of the way we are rewarded.The incentive layer must be improved.

Increase keepers premium
I’m quite sure that projects willing to delegate these tasks to keepers will be willing to pay way more than the current price, especially with the safety that comes with the multiplicity of keepers running on their behalf, to support their respective networks. Prices should be raised.

Avoid gas war
My second concern is related to front-running bots. With the current system, we will end up with bots taking a ridiculus profit by estimating the perfect gas expense by transaction - and most of the value added provided by the protocol will be granted to ethereum miners/stakers. A solution would be to share the premium of a successfull transaction with all the other keepers. I’m not going into the details as i don’t have all the answers, but it’s definitely something that might help.

Otherwise, excellent job. The future is bright !


Agreed on both. Busy working on a new increased reward mechanism based on bond. The gas war one is a bit more tricky, since you don’t want to reward idle keepers (then you are just promoting rent seeking behavior). I don’t have any current proposed solutions for it unfortunately, but definitely a good discussion to start!

Will deploy a new Keep3rV1Helper candidate and release here so we can discuss.


Released a new Keep3rV1Helper candidate;

This will distribute rewards between 1.0 and 2.5 based on how much KP3R you have bonded up to the maximum at 2.5 at 100 KP3R.

As soon as the new Keep3rV1Oracle is out then we can integrate that to do ETH gas price adjustments as well, so this is an interim proposal.


Great idea, so just confirming that this means if keeper work for a job, then the reward given to them is base on the amount of KP3R they bonded and the gas fee. Is that correct?

The proposed formula is as follows (until Keep3rV1Oracle is active);

  1. Calculate gas cost (gasUsed in wei * fastGas price) =: min
  2. Calculate boosted value; min * 2.5 =: boost
  3. Calculate bonded amount; Math.min(bond[KP3R], 100 KP3R) =: bonded
  4. Calculate bonded boost; boost * bonded / 100 KP3R =: max
  5. Calculate KP3R amount Math.max(min, max)

So looking at a practical example with the following variables;

-Example 1-

gasUsed = 100,000
fastGas = 40
bonded = 10

min = 100,000 * 40 = 4,000,000
boost = min * 2.5 = 4,000,000 * 2.5 = 10,000,000
bonded = Math.min(10, 100) = 10
max = boost * bonded / 100 = 10,000,000 * 10 / 100 = 1,000,000
KP3R = Math.max(min, max) = Math.max(4,000,000, 1,000,000) = 4,000,000

-Example 2-

gasUsed = 100,000
fastGas = 40
bonded = 50

min = 100,000 * 40 = 4,000,000
boost = min * 2.5 = 4,000,000 * 2.5 = 10,000,000
bonded = Math.min(50, 100) = 50
max = boost * bonded / 100 = 10,000,000 * 50 / 100 = 5,000,000
KP3R = Math.max(min, max) = Math.max(4,000,000, 5,000,000) = 5,000,000

-Example 3-

gasUsed = 100,000
fastGas = 40
bonded = 100

min = 100,000 * 40 = 4,000,000
boost = min * 2.5 = 4,000,000 * 2.5 = 10,000,000
bonded = Math.min(100, 100) = 100
max = boost * bonded / 100 = 10,000,000 * 100 / 100 = 10,000,000
KP3R = Math.max(min, max) = Math.max(4,000,000, 10,000,000) = 10,000,000

Hope that helps


Thank you! That is some clear method explanation.

wouldnt that start a gas war?

Competition is unavoidable. That’s why rewards are capped at FASTGAS

1 Like

I have been brainstorming some ideas that might prevent gas wars. I can make a forum post later once I gathered my thoughts, but the main idea I have been pondering is a job that allows K3PRs that perform the job first to become the only K3PR able to perform that job for at least some time.

Once a K3PR becomes a privileged K3PR, the job can define an uptime, and if a job isn’t completed within an appropriate time, the current privileged K3PR can be banned for a time and the next K3PR to perform the job can be given a bonus for noticing that the job went past its SLA and filling in for the dedicated K3PR that failed its promise to perform the job in a timely fashion.

The job implementing this spec could also limit how long a K3PR can be privileged and implement rewards that trail off or ramp up depending on how they want to incentivize.

The idea is that you would not have a gas war while a K3PR is privileged. The only gas war might start if a privileged K3PR goes down and a bunch of K3PRs want to be the next dedicated one. But I feel like that kind of gas war might be fine. The one willing to spend the most gas might be showing that they are willing to recoup that one-time cost to become privileged by not missing jobs.

I’ll split this into its own post once I solidify my thoughts and perhaps I can provide a proof-of-concept implementation.


If you put in place any limitation on the gas price that can be paid by a keeper… then you risk killing kp3r system all together, as bots that don’t follow the gas price constraints of kp3r will front run kp3r bots… The only solution to that is forcing projects to adopt kp3r as the only keeper, which is kind of a stretch and I’m sure not possible… In other words gas wars can’t be avoided without increasing dependency on kp3r.

Simply put the current Keeper rewards proposed by @andre.cronje will be as below:

If Bonded KP3R is <=40: Reward Multiple is 1.
If Bonded KP3R is > 40 & <=100: Reward multiple is: (Bonded KP3R)/40
If Bonded KP3R is > 100: Reward multiple is 2.5

So if 50 KP3R is bonded:
Reward multiple is 50/40 = 1.25
i.e if the gas cost is 4.000,000: Reward is 4,000,000*1.25: 5,000,000

With current KP3R price at ~$200, anyone with less than $8000 (40*200) bonded doesn’t earn any premium.


Why not using the deviation between tx.gasprice and the Oracle’s fastGas ; so that using higher gas prices would result in less rewards?

The cap is to stop gas front-running & gas wars. Otherwise someone could just say gasprice = 999999 and get rewarded for all the jobs Keep3r credit.


that means whoever got less than 40 bonded is losing money.

  • by doing jobs lose because gas fees > reward
  • by not doing jobs, for being inactive.

I only have 6 kp3r, because they do not design something attractive for those who have my situation the same

well the point is to have not too many keepers (otherwise the chance of hit is too low) and not too few (otherwise the chance of anyone participating is too low)

Congratulations on Keep3r project it,s great to have Andre Cronje on the Yearn.Finance community forum

1 Like

By the way, why does the deployed helper end up multiplying by PRICE which is set to 10?

The proposal and latest github commit shows this code snippet:

function getQuoteLimitFor(address origin, uint gasUsed) public view returns (uint) {
uint _min = gasUsed.mul(uint(FASTGAS.latestAnswer()));
uint _boost = _min.mul(BOOST).div(BASE); // increase by 2.5
uint _bond = Math.min(bonds(origin), TARGETBOND);
return Math.max(_min, _boost.mul(_bond).div(TARGETBOND));

But this is the deployed one:

uint constant public PRICE = 10;
function getQuoteLimitFor(address origin, uint gasUsed) public view returns (uint) {
uint _min = gasUsed.mul(PRICE).mul(uint(FASTGAS.latestAnswer()));
uint _boost = _min.mul(BOOST).div(BASE); // increase by 2.5
uint _bond = Math.min(bonds(origin), TARGETBOND);
return Math.max(_min, _boost.mul(_bond).div(TARGETBOND));

Is this why txs with really high gas prices are netting so much reward? See this one for example: Analysis

The gas oracle return 95 gwei, but the keep3r used 129.06 as a price and still made 0.998 KP3R ($121.38) on a tx fee of 0.1502 Eth (129.06 Gwei, 1,163,980 used). This KP3R also has a small bond, so it gets the min amount.

Is this because the helper doesn’t use the Uniswap oracle to find the price of KP3R yet?

I couldn’t find in the code where a ratio of Eth to KP3R is determined, except it seems as if the ratio of ETH to KP3R is currently hardcoded as 10:1 with that PRICE variable.

1 Like

Until uniquote has enough data points the ratio is fixed at 10:1, will propose a new helper tomorrow.


Gotcha, makes sense to me. I figured Uniquote would be the natural choice for price determination in the helper. Thanks for the update!