Skip to content
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

Remove unchecked arithmetics #162

Open
wants to merge 1 commit into
base: update/ink-5.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions contracts/src/finance/payment_splitter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

use crate::traits::errors::MathError;
pub use crate::{
payment_splitter,
traits::payment_splitter::*,
Expand Down Expand Up @@ -160,18 +161,25 @@ pub trait InternalImpl: Storage<Data> + Internal {
let balance = Self::env().balance();
let current_balance = balance.checked_sub(Self::env().minimum_balance()).unwrap_or_default();
let total_released = self.data().total_released.get_or_default();
let total_received = current_balance + total_released;
let total_received = current_balance.checked_add(total_released).ok_or(MathError::Overflow)?;
let shares = self.data().shares.get(&account).unwrap();
let total_shares = self.data().total_shares.get_or_default();
let released = self.data().released.get(&account).unwrap_or_default();
let payment = total_received * shares / total_shares - released;
let payment = total_received
.checked_mul(shares).ok_or(MathError::Overflow)? // total_received * shares
.checked_div(total_shares).ok_or(MathError::DivByZero)? // (total_received * shares) / total_shares
.checked_sub(released).ok_or(MathError::Underflow)?; // (total_received * shares) / total_shares - released

if payment == 0 {
return Err(PaymentSplitterError::AccountIsNotDuePayment)
}

self.data().released.insert(&account, &(released + payment));
self.data().total_released.set(&(total_released + payment));
self.data()
.released
.insert(&account, &(released.checked_add(payment).ok_or(MathError::Overflow)?)); // released + payment
self.data()
.total_released
.set(&(total_released.checked_add(payment).ok_or(MathError::Overflow)?)); // total_released + payment

let transfer_result = Self::env().transfer(account, payment);
if transfer_result.is_err() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ use crate::{
governor::GovernorStorageGetters,
},
traits::{
errors::GovernanceError,
errors::{
GovernanceError,
MathError,
},
governance::{
ProposalId,
VoteType,
Expand All @@ -49,7 +52,7 @@ pub trait CountingInternal: Storage<Data> + QuorumImpl + GovernorStorageGetters
let num_votes = proposal_vote
.for_votes
.checked_add(proposal_vote.abstain_votes)
.ok_or(GovernanceError::Overflow)?;
.ok_or(MathError::Overflow)?;

Ok(self.quorum(self._proposal_snapshot(proposal_id)?)? <= num_votes)
}
Expand Down Expand Up @@ -85,19 +88,16 @@ pub trait CountingInternal: Storage<Data> + QuorumImpl + GovernorStorageGetters
proposal_vote.against_votes = proposal_vote
.against_votes
.checked_add(weight)
.ok_or(GovernanceError::Overflow)?;
.ok_or(MathError::Overflow)?;
}
VoteType::For => {
proposal_vote.for_votes = proposal_vote
.for_votes
.checked_add(weight)
.ok_or(GovernanceError::Overflow)?;
proposal_vote.for_votes = proposal_vote.for_votes.checked_add(weight).ok_or(MathError::Overflow)?;
}
VoteType::Abstain => {
proposal_vote.abstain_votes = proposal_vote
.abstain_votes
.checked_add(weight)
.ok_or(GovernanceError::Overflow)?;
.ok_or(MathError::Overflow)?;
}
}

Expand Down
13 changes: 9 additions & 4 deletions contracts/src/governance/extensions/governor_quorum/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ use crate::{
TimestampProvider,
},
},
traits::governance::utils::votes::*,
traits::{
errors::MathError,
governance::utils::votes::*,
},
};
use openbrush::traits::{
Storage,
Expand Down Expand Up @@ -105,11 +108,13 @@ pub trait QuorumImpl:

let past_total_supply = VotesRef::get_past_total_supply(&mut token, timestamp)?;

past_total_supply
let result = past_total_supply
.checked_mul(self.quorum_numerator_at(timestamp))
.ok_or(GovernanceError::Overflow)?
.ok_or(MathError::Overflow)?
.checked_div(self.quorum_denominator())
.ok_or(GovernanceError::Overflow)
.ok_or(MathError::Overflow)?;

Ok(result)
}

/// Updates the quorum numerator
Expand Down
9 changes: 6 additions & 3 deletions contracts/src/governance/utils/votes/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ use crate::{
VotesEvents,
},
},
traits::errors::GovernanceError,
traits::errors::{
GovernanceError,
MathError,
},
};
use openbrush::{
traits::{
Expand Down Expand Up @@ -160,11 +163,11 @@ pub trait VotesInternal: Storage<Data> + VotesEvents + TimestampProvider {
}

fn _add(a: u128, b: u128) -> Result<u128, GovernanceError> {
Ok(a.checked_add(b).ok_or(GovernanceError::Overflow)?)
Ok(a.checked_add(b).ok_or(MathError::Overflow)?)
}

fn _sub(a: u128, b: u128) -> Result<u128, GovernanceError> {
Ok(a.checked_sub(b).ok_or(GovernanceError::Overflow)?)
Ok(a.checked_sub(b).ok_or(MathError::Overflow)?)
}

/// Returns the number of voting units owned by `account`.
Expand Down
9 changes: 7 additions & 2 deletions contracts/src/token/psp22/extensions/capped.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,14 @@ pub trait InternalImpl: Storage<Data> + Internal + PSP22 {
}

fn _is_cap_exceeded(&self, amount: &Balance) -> bool {
if self.total_supply() + amount > Internal::_cap(self) {
return true
let supply = self.total_supply().checked_add(*amount);

if let Some(supply) = supply {
if supply > Internal::_cap(self) {
return true
}
}

false
}

Expand Down
22 changes: 19 additions & 3 deletions contracts/src/token/psp22/extensions/flashmint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

use crate::traits::errors::MathError;
pub use crate::{
psp22,
psp22::extensions::flashmint,
Expand Down Expand Up @@ -72,11 +73,26 @@ pub trait FlashLenderImpl: Storage<psp22::Data> + psp22::Internal + PSP22 + Inte
Internal::_on_flashloan(self, receiver_account, token, fee, amount, data)?;
let this = Self::env().account_id();
let current_allowance = self.allowance(receiver_account, this);
if current_allowance < amount + fee {

if current_allowance < amount.checked_add(fee).ok_or(MathError::Overflow)? {
// amount + fee
return Err(FlashLenderError::AllowanceDoesNotAllowRefund)
}
psp22::Internal::_approve_from_to(self, receiver_account, this, current_allowance - amount - fee)?;
psp22::Internal::_burn_from(self, receiver_account, amount + fee)?;
psp22::Internal::_approve_from_to(
self,
receiver_account,
this,
current_allowance
.checked_sub(amount)
.ok_or(MathError::Underflow)?
.checked_sub(fee)
.ok_or(MathError::Underflow)?, // current_allowance - amount - fee
)?;
psp22::Internal::_burn_from(
self,
receiver_account,
amount.checked_add(fee).ok_or(MathError::Overflow)?, // amount + fee
)?;
Ok(())
}
}
Expand Down
74 changes: 48 additions & 26 deletions contracts/src/token/psp22/psp22.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

use crate::traits::errors::MathError;
pub use crate::{
psp22,
traits::psp22::*,
Expand Down Expand Up @@ -85,11 +86,11 @@ pub trait PSP22Impl: Storage<Data> + Internal {
let caller = Self::env().caller();
let allowance = self._allowance(&from, &caller);

if allowance < value {
return Err(PSP22Error::InsufficientAllowance)
}

self._approve_from_to(from, caller, allowance - value)?;
self._approve_from_to(
from,
caller,
allowance.checked_sub(value).ok_or(PSP22Error::InsufficientAllowance)?,
)?;
self._transfer_from_to(from, to, value, data)?;
Ok(())
}
Expand All @@ -102,18 +103,26 @@ pub trait PSP22Impl: Storage<Data> + Internal {

fn increase_allowance(&mut self, spender: AccountId, delta_value: Balance) -> Result<(), PSP22Error> {
let owner = Self::env().caller();
self._approve_from_to(owner, spender, self._allowance(&owner, &spender) + delta_value)

let new_allowance = self
._allowance(&owner, &spender)
.checked_add(delta_value)
.ok_or(MathError::Overflow)?;

self._approve_from_to(owner, spender, new_allowance)
}

fn decrease_allowance(&mut self, spender: AccountId, delta_value: Balance) -> Result<(), PSP22Error> {
let owner = Self::env().caller();
let allowance = self._allowance(&owner, &spender);

if allowance < delta_value {
return Err(PSP22Error::InsufficientAllowance)
}

self._approve_from_to(owner, spender, allowance - delta_value)
self._approve_from_to(
owner,
spender,
allowance
.checked_sub(delta_value)
.ok_or(PSP22Error::InsufficientAllowance)?,
)
}
}

Expand Down Expand Up @@ -182,18 +191,18 @@ pub trait InternalImpl: Storage<Data> + Internal {
amount: Balance,
_data: Vec<u8>,
) -> Result<(), PSP22Error> {
let from_balance = Internal::_balance_of(self, &from);

if from_balance < amount {
return Err(PSP22Error::InsufficientBalance)
}
let from_balance = Internal::_balance_of(self, &from)
.checked_sub(amount)
.ok_or(PSP22Error::InsufficientBalance)?;

Internal::_before_token_transfer(self, Some(&from), Some(&to), &amount)?;

self.data().balances.insert(&from, &(from_balance - amount));
self.data().balances.insert(&from, &from_balance);

let to_balance = Internal::_balance_of(self, &to);
self.data().balances.insert(&to, &(to_balance + amount));
self.data()
.balances
.insert(&to, &(to_balance.checked_add(amount).ok_or(MathError::Overflow)?));

Internal::_after_token_transfer(self, Some(&from), Some(&to), &amount)?;
Internal::_emit_transfer_event(self, Some(from), Some(to), amount);
Expand All @@ -209,11 +218,19 @@ pub trait InternalImpl: Storage<Data> + Internal {

fn _mint_to(&mut self, account: AccountId, amount: Balance) -> Result<(), PSP22Error> {
Internal::_before_token_transfer(self, None, Some(&account), &amount)?;
let mut new_balance = Internal::_balance_of(self, &account);
new_balance += amount;
let new_balance = Internal::_balance_of(self, &account)
.checked_add(amount)
.ok_or(MathError::Overflow)?; // balance + amount

self.data().balances.insert(&account, &new_balance);

let new_supply = self.data().supply.get_or_default() + amount;
let new_supply = self
.data()
.supply
.get_or_default()
.checked_add(amount)
.ok_or(MathError::Overflow)?; // supply + amount

self.data().supply.set(&new_supply);

Internal::_after_token_transfer(self, None, Some(&account), &amount)?;
Expand All @@ -225,16 +242,21 @@ pub trait InternalImpl: Storage<Data> + Internal {
fn _burn_from(&mut self, account: AccountId, amount: Balance) -> Result<(), PSP22Error> {
let mut from_balance = Internal::_balance_of(self, &account);

if from_balance < amount {
return Err(PSP22Error::InsufficientBalance)
}
from_balance = from_balance
.checked_sub(amount)
.ok_or(PSP22Error::InsufficientBalance)?; // balance - amount

Internal::_before_token_transfer(self, Some(&account), None, &amount)?;

from_balance -= amount;
self.data().balances.insert(&account, &from_balance);

let new_supply = self.data().supply.get_or_default() - amount;
let new_supply = self
.data()
.supply
.get_or_default()
.checked_sub(amount)
.ok_or(MathError::Underflow)?; // supply - amount

self.data().supply.set(&new_supply);

Internal::_after_token_transfer(self, Some(&account), None, &amount)?;
Expand Down
Loading