-
Notifications
You must be signed in to change notification settings - Fork 46
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
audit fixes (2) #775
audit fixes (2) #775
Changes from all commits
bbff637
4303c0c
767f452
8100d57
aba2e4e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -196,12 +196,12 @@ pub trait FarmContract { | |
) { | ||
let farm_token_mapper = sc.farm_token(); | ||
for farm_position in farm_positions { | ||
farm_token_mapper.require_same_token(&farm_position.token_identifier); | ||
|
||
if sc.is_old_farm_position(farm_position.token_nonce) { | ||
continue; | ||
} | ||
|
||
farm_token_mapper.require_same_token(&farm_position.token_identifier); | ||
|
||
let token_attributes: FarmTokenAttributes<<Self::FarmSc as ContractBase>::Api> = | ||
farm_token_mapper.get_token_attributes(farm_position.token_nonce); | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we extract the increase/decrease of the user_farm_position outside of the for, to improve the gas consumption? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll add it in the new PR. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, it can be used only for increase position, as decrease position function needs the entire looped payment to check the attributes and decrease for the original owner. I'll see if there is any improvement if we send the original_owner as a parameter, instead of the payment. |
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,8 @@ pub type DoubleMultiPayment<M> = MultiValue2<EsdtTokenPayment<M>, EsdtTokenPayme | |
pub type ClaimRewardsResultType<M> = DoubleMultiPayment<M>; | ||
pub type ExitFarmResultType<M> = DoubleMultiPayment<M>; | ||
|
||
pub const DEFAULT_FARM_POSITION_MIGRATION_NONCE: u64 = 1; | ||
|
||
pub struct ClaimRewardsResultWrapper<M: ManagedTypeApi> { | ||
pub new_farm_token: EsdtTokenPayment<M>, | ||
pub rewards: EsdtTokenPayment<M>, | ||
|
@@ -204,20 +206,37 @@ pub trait BaseFunctionsModule: | |
reward | ||
} | ||
|
||
fn migrate_old_farm_positions(&self, caller: &ManagedAddress) { | ||
fn migrate_old_farm_positions(&self, caller: &ManagedAddress) -> BigUint { | ||
let payments = self.get_non_empty_payments(); | ||
let farm_token_mapper = self.farm_token(); | ||
let farm_token_id = farm_token_mapper.get_token_id(); | ||
let mut migrated_amount = BigUint::zero(); | ||
for farm_position in &payments { | ||
if farm_position.token_identifier == farm_token_id | ||
&& self.is_old_farm_position(farm_position.token_nonce) | ||
{ | ||
let mut user_total_farm_position = self.get_user_total_farm_position(caller); | ||
user_total_farm_position.total_farm_position += farm_position.amount; | ||
self.user_total_farm_position(caller) | ||
.set(user_total_farm_position); | ||
migrated_amount += farm_position.amount; | ||
} | ||
} | ||
|
||
if migrated_amount > 0 { | ||
let mut user_total_farm_position = self.get_user_total_farm_position(caller); | ||
user_total_farm_position.total_farm_position += &migrated_amount; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A gas improvement here could be an update instead of a get + set. (see the
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know if this optimizes the gas cost as much, as we still need to check if the storage is empty before the update function. And also, this would mean another function, which would increase the contract size (even if by a small margin). |
||
self.user_total_farm_position(caller) | ||
.set(user_total_farm_position); | ||
} | ||
|
||
migrated_amount | ||
} | ||
|
||
fn decrease_old_farm_positions(&self, migrated_amount: BigUint, caller: &ManagedAddress) { | ||
if migrated_amount == BigUint::zero() { | ||
return; | ||
} | ||
self.user_total_farm_position(caller) | ||
.update(|user_total_farm_position| { | ||
user_total_farm_position.total_farm_position -= migrated_amount; | ||
}); | ||
} | ||
|
||
fn end_produce_rewards<FC: FarmContract<FarmSc = Self>>(&self) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -49,20 +49,37 @@ pub trait ClaimOnlyBoostedStakingRewardsModule: | |
boosted_rewards_payment | ||
} | ||
|
||
fn migrate_old_farm_positions(&self, caller: &ManagedAddress) { | ||
fn migrate_old_farm_positions(&self, caller: &ManagedAddress) -> BigUint { | ||
let payments = self.call_value().all_esdt_transfers().clone_value(); | ||
let farm_token_mapper = self.farm_token(); | ||
let farm_token_id = farm_token_mapper.get_token_id(); | ||
let mut migrated_amount = BigUint::zero(); | ||
for farm_position in &payments { | ||
if farm_position.token_identifier == farm_token_id | ||
&& self.is_old_farm_position(farm_position.token_nonce) | ||
{ | ||
let mut user_total_farm_position = self.get_user_total_farm_position(caller); | ||
user_total_farm_position.total_farm_position += farm_position.amount; | ||
self.user_total_farm_position(caller) | ||
.set(user_total_farm_position); | ||
migrated_amount += farm_position.amount; | ||
} | ||
} | ||
|
||
if migrated_amount > 0 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why do we have duplicated code ? Can't you add this into base function ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The farm staking contract does not import the base_functions module as there are some variables that are Farm only specific. Maybe we could rewrite this to be more generic. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We cannot do that due to Token Attributes. I think it's difficult to rewrite the code write now. The code changes will be huge and we would have to re-audit the whole solution. |
||
let mut user_total_farm_position = self.get_user_total_farm_position(caller); | ||
user_total_farm_position.total_farm_position += &migrated_amount; | ||
self.user_total_farm_position(caller) | ||
.set(user_total_farm_position); | ||
} | ||
|
||
migrated_amount | ||
} | ||
|
||
fn decrease_old_farm_positions(&self, migrated_amount: BigUint, caller: &ManagedAddress) { | ||
if migrated_amount == BigUint::zero() { | ||
return; | ||
} | ||
self.user_total_farm_position(caller) | ||
.update(|user_total_farm_position| { | ||
user_total_farm_position.total_farm_position -= migrated_amount; | ||
}); | ||
} | ||
|
||
// Cannot import the one from farm, as the Wrapper struct has different dependencies | ||
|
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.
Can we optimize here the storage access for user_farm_position? After the for, settle with increase/decrease of user_farm_position.