-
Notifications
You must be signed in to change notification settings - Fork 142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add stake-cw20-external-rewards #170
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good :) Just couple minor comments
if env.block.height > msg.start_block { | ||
return Err(ContractError::StartBlockAlreadyOccurred {}); | ||
} | ||
if msg.start_block > msg.end_block { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be >=
? Currently could instantiate a contract that starts and ends at the same block and it would be valid so long as that block was a multiple of payment_block_delta
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, this would would result in one payment. Probable not the best practice and a seperate contract should be written for these cases, but nothing invalid about this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a test case for this? If not we should make a TODO / issue. Can be added in a separate PR.
Ok(match config.clone().denom { | ||
Denom::Native(denom) => BankMsg::Send { | ||
to_address: info.sender.to_string(), | ||
amount: vec![Coin { amount, denom }], | ||
} | ||
.into(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok(match config.clone().denom { | |
Denom::Native(denom) => BankMsg::Send { | |
to_address: info.sender.to_string(), | |
amount: vec![Coin { amount, denom }], | |
} | |
.into(), | |
Ok(match &config.denom { | |
Denom::Native(denom) => BankMsg::Send { | |
to_address: info.sender.to_string(), | |
amount: vec![Coin { amount, denom: denom.to_string() }], | |
} | |
.into(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Me like.
) -> Result<Response, ContractError> { | ||
validate_instantiate_msg(&env, &msg)?; | ||
let config = Config { | ||
start_block: msg.start_block, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the rationale for having the user pass in start_block, end_block, and payment per block? It would be more elegant to accept a duration and an amount, and then calculate payment per unit time within the contract. I do something similar here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like that the parameters are explicit and the instatiator is required to double check everything will function as expected.
if config.denom != Denom::Cw20(info.sender) { | ||
return Err(ContractError::IncorrectDenom {}); | ||
} | ||
if amount != config.total_amount { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe change to amount >= config.total_amount, and refund any extra funds that were sent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like require the instatiator to be precise with their inputs. Failing the instatiate requires them to revaluate the inputs and ensure they are doing what they intend to do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, agree with @ben2x4 on this one.
let delta = config.payment_block_delta; | ||
let mut current_block = last_claimed; | ||
let mut amount = Uint128::zero(); | ||
while current_block <= min(up_to_block, config.end_block) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I see. ClaimUpToBlock can be used to prevent out of gas issue here
amount: Uint128, | ||
) -> Result<Response, ContractError> { | ||
let mut config = CONFIG.load(deps.storage)?; | ||
if config.funded { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't you be able to top up this contract whenever the rewards get depleted. Otherwise, you'd have to instantiate a new contract every time you want to allocate more rewards
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah this is a good additional feature
This is a solid start. There are a few major issues though:
|
Co-authored-by: zeke <[email protected]>
Co-authored-by: zeke <[email protected]>
I agree that point 2 is a great feature to implement before production deployment. In regards to point 1, need to look a little more deeply into how they implement this. Would love to chat. |
…ao into stake-cw20-external-rewards
Can we please rebase this branch to make it easier to merge in PRs potentially? 🙏 |
same "printed page" as the copyright notice for easier | ||
identification within third-party archives. | ||
|
||
Copyright [yyyy] [name of copyright owner] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update this to be either your name or DAO DAO please. : )
@@ -0,0 +1,108 @@ | |||
# CosmWasm Starter Pack |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The most basic README would be nice. Can remove all of this template stuff.
let (amount, _) = get_amount_owed( | ||
deps, | ||
&address, | ||
&config, | ||
last_claimed.block_height, | ||
env.block.height, | ||
)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could get expensive?
have you all checked out the repo from cw20 - reward. its just like anchor on terra and yield protocol on ethereum |
Ben also needs it to support multiple reward tokens for a single staking contract. But I agree, this is a good start. |
This approach is flawed, implementing this with a different method |
This contract distributes external staking rewards to stakers in the
stake-cw20
contract. External means the rewards is either a native or cw20 that is not the same as the cw20 being staked.The contract calculates rewards based on blocks but only distributes them at predefined epochs. This is all configurable in the instatiation message.