Skip to content

Commit

Permalink
Fix for HAL-02 issue.
Browse files Browse the repository at this point in the history
Now only Created and Reclaimed bids can be picked.
  • Loading branch information
kubaplas committed May 6, 2024
1 parent d7a2279 commit 96b5465
Show file tree
Hide file tree
Showing 10 changed files with 95 additions and 2 deletions.
2 changes: 1 addition & 1 deletion dao/src/bid_escrow/bid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use odra::types::{Address, Balance, BlockTime};
use odra::OdraType;

/// Bid status representation
#[derive(OdraType, PartialEq, Debug)]
#[derive(OdraType, PartialEq, Debug, Copy)]
pub enum BidStatus {
/// Placed, awaiting to be picked.
Created,
Expand Down
1 change: 1 addition & 0 deletions dao/src/bid_escrow/bid_engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ impl BidEngine {
cspr_amount,
stake: bid.reputation_stake,
external_worker_cspr_stake: bid.cspr_stake.unwrap_or_default(),
bid_status: bid.status,
};

let job = Job::new(&pick_bid_request);
Expand Down
8 changes: 7 additions & 1 deletion dao/src/bid_escrow/job.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
//! Bid-related structs.
use crate::bid_escrow::bid::BidStatus;
use crate::bid_escrow::types::{BidId, JobId, JobOfferId};
use crate::rules::validation::bid_escrow::{CanPickBid, DoesProposedPaymentMatchTransferred};
use crate::rules::validation::bid_escrow::{
CanBidBePicked, CanPickBid, DoesProposedPaymentMatchTransferred,
};
use crate::rules::RulesBuilder;
use crate::utils::types::DocumentHash;
use crate::utils::Error;
Expand Down Expand Up @@ -54,6 +57,8 @@ pub struct PickBidRequest {
pub stake: Balance,
/// Bid CSPR stake - for an [External Worker](crate::bid_escrow#definitions).
pub external_worker_cspr_stake: Balance,
/// Bid status
pub bid_status: BidStatus,
}

/// Data required to reclaim the Job.
Expand Down Expand Up @@ -113,6 +118,7 @@ impl Job {
pub fn new(request: &PickBidRequest) -> Self {
RulesBuilder::new()
.add_validation(CanPickBid::create(request.caller, request.poster))
.add_validation(CanBidBePicked::create(request.bid_status))
.add_validation(DoesProposedPaymentMatchTransferred::create(
request.payment,
request.transferred_cspr,
Expand Down
22 changes: 22 additions & 0 deletions dao/src/rules/validation/bid_escrow/can_bid_be_picked.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use crate::bid_escrow::bid::BidStatus;
use crate::rules::validation::Validation;
use crate::utils::Error;
use macros::Rule;

/// Makes sure the job poster is the one who picks the [`Bid`](crate::bid_escrow::bid::Bid).
/// May return [Error::OnlyJobPosterCanPickABid].
#[derive(Rule)]
pub struct CanBidBePicked {
bid_status: BidStatus,
}

impl Validation for CanBidBePicked {
fn validate(&self) -> Result<(), Error> {
match self.bid_status {
BidStatus::Created | BidStatus::Reclaimed => Ok(()),
BidStatus::Picked => Err(Error::BidAlreadyPicked),
BidStatus::Canceled => Err(Error::BidCanceled),
BidStatus::Rejected => Err(Error::BidRejected),
}
}
}
2 changes: 2 additions & 0 deletions dao/src/rules/validation/bid_escrow/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Groups [Bid Escrow](crate::bid_escrow)-related validations.
mod can_be_onboarded;
mod can_bid_be_cancelled;
mod can_bid_be_picked;
mod can_bid_on_auction_state;
mod can_bid_on_own_job;
mod can_job_offer_be_cancelled;
Expand All @@ -19,6 +20,7 @@ mod is_stake_non_zero;

pub use can_be_onboarded::CanBeOnboarded;
pub use can_bid_be_cancelled::CanBidBeCancelled;
pub use can_bid_be_picked::CanBidBePicked;
pub use can_bid_on_auction_state::CanBidOnAuctionState;
pub use can_bid_on_own_job::CanBidOnOwnJob;
pub use can_job_offer_be_cancelled::CanJobOfferBeCancelled;
Expand Down
3 changes: 3 additions & 0 deletions dao/src/utils/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ execution_error! {
OnboardedWorkerCannotStakeCSPR => 4035,
NotOnboardedWorkerMustStakeCSPR => 4036,
CannotStakeBothCSPRAndReputation => 4037,
BidAlreadyPicked => 4038,
BidCanceled => 4039,
BidRejected => 4040,

// Reputation Token Errors.
CannotStakeTwice => 4500,
Expand Down
19 changes: 19 additions & 0 deletions dao/tests/common/contracts/bid_escrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,25 @@ impl DaoWorld {
);
}

pub fn pick_bid_failed(&mut self, job_poster: Account, worker: Account) {
let job_poster = self.get_address(&job_poster);
let worker = self.get_address(&worker);
let job_offer_id = self.offers.get(&job_poster).expect("Job Offer not found.");
let bid_id = self
.bids
.get(&(*job_offer_id, worker))
.expect("Bid id not found.");
let bid = self.bid_escrow.get_bid(*bid_id).expect("Bid not found.");
test_env::set_caller(job_poster);
test_env::assert_exception(Error::BidCanceled, || {
self.bid_escrow.with_tokens(bid.proposed_payment).pick_bid(
*job_offer_id,
*bid_id,
bid.proposed_payment,
);
});
}

pub fn pick_bid_without_enough_payment(&mut self, job_poster: Account, worker: Account) {
let job_poster = self.get_address(&job_poster);
let worker = self.get_address(&worker);
Expand Down
35 changes: 35 additions & 0 deletions dao/tests/features/bid_escrow/hal-02-pick_canceled_bid.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
Feature: Pick a canceled bid
JobPoster cannot pick a bid that has already been cancelled.
This is a presentation of HAL-02 issue fix.
Background:
Given accounts
| account | CSPR balance | REP balance | REP stake | is_kyced | is_va |
| JobPoster | 1000 | 0 | 0 | true | false |
| Alice | 1000 | 0 | 0 | true | false |
| ExternalWorker | 1000 | 0 | 0 | true | false |
| InternalWorker | 0 | 1000 | 0 | true | true |
| VA1 | 0 | 1000 | 0 | true | true |
| VA2 | 0 | 1000 | 0 | true | true |
When JobPoster posted a JobOffer with expected timeframe of 14 days, maximum budget of 1000 CSPR and 400 CSPR DOS Fee
And 2 days passed
And Alice posted a JobOffer with expected timeframe of 20 days, maximum budget of 2000 CSPR and 400 CSPR DOS Fee
Scenario: JobPoster try to pick the cancelled bid
When InternalWorker posted the Bid for JobOffer 0 with proposed timeframe of 7 days and 500 CSPR price and 100 REP stake
Then InternalWorker Bid is posted
And balances are
| account | CSPR balance | REP balance | REP stake |
| InternalWorker | 0 | 1000 | 100 |
When InternalWorker posted the Bid for JobOffer 1 with proposed timeframe of 7 days and 500 CSPR price and 200 REP stake
Then InternalWorker Bid is posted
And balances are
| account | CSPR balance | REP balance | REP stake |
| InternalWorker | 0 | 1000 | 300 |
When 2 days passed
And InternalWorker cancels the Bid for JobPoster
Then Bid 0 is canceled
And balances are
| account | CSPR balance | REP balance | REP stake |
| InternalWorker | 0 | 1000 | 200 |
When 1 days passed
Then JobPoster fails to pick the Bid of InternalWorker

5 changes: 5 additions & 0 deletions dao/tests/steps/bid_escrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,3 +258,8 @@ fn cannot_submit_job_proof_second_time(w: &mut DaoWorld, worker: Account, job_id
bid_escrow.submit_job_proof(job_id, DocumentHash::from("Job Proof"))
});
}

#[then(expr = "{account} fails to pick the Bid of {account}")]
fn bid_pick_failed(w: &mut DaoWorld, job_poster: Account, worker: Account) {
w.pick_bid_failed(job_poster, worker);
}

0 comments on commit 96b5465

Please sign in to comment.