1

I have a smart contract i am working with, in the acceptOffer function, i need to invalidate all previous Offer, by using isAccepted(boolean) back to false,I have search online looking for a way to get it working, and also tried

#[derive(Accounts)]
#[instruction()]
pub struct AcceptOffer<'info> {
    #[account(
        mut,
        seeds = [USER_TAG,authority.key().as_ref()],
        bump,
        has_one = authority
    )]
    pub user: Box<Account<'info, User>>,
    #[account(mut)]
    pub authority: Signer<'info>,
    #[account(mut)]
    pub offer: Box<Account<'info, Offer>>,
    #[account(mut)]
    pub previous_offers: Box<Account<'info, Offer>>, // added this line
    #[account(mut)]
    pub request: Box<Account<'info, Request>>,
    pub system_program: Program<'info, System>,
}

but i get error proc-macro panicked: Invariant violation: composite constraints can only be raw or literals

this are my code snippet,the commented section is what I am trying to achieve

#[derive(Accounts)]
#[instruction()]
pub struct AcceptOffer<'info> {
    #[account(
        mut,
        seeds = [USER_TAG,authority.key().as_ref()],
        bump,
        has_one = authority
    )]
    pub user: Box<Account<'info, User>>,
    #[account(mut)]
    pub authority: Signer<'info>,
    #[account(mut)]
    pub offer: Box<Account<'info, Offer>>,
    #[account(mut)]
    pub request: Box<Account<'info, Request>>,
    pub system_program: Program<'info, System>,
}




    pub fn accept_offer(ctx: Context<AcceptOffer>) -> Result<()> {
        let user = &mut ctx.accounts.user;
        let offer = &mut ctx.accounts.offer;
        let request = &mut ctx.accounts.request;

        if user.account_type != AccountType::Buyer {
            return err!(MarketplaceError::OnlyBuyersAllowed);
        }

        if request.buyer_id != user.id {
            return err!(MarketplaceError::UnauthorizedBuyer);
        }

        if offer.is_accepted {
            return err!(MarketplaceError::OfferAlreadyAccepted);
        }

        if Clock::get().unwrap().unix_timestamp as u64 > request.updated_at + TIME_TO_LOCK
            && request.lifecycle == RequestLifecycle::AcceptedByBuyer
        {
            return err!(MarketplaceError::RequestLocked);
        }

        //TODO: fix this reset

        // for prev_offer_id in request.offer_ids.iter() {
        //     // let previous_offer = &mut ctx.accounts.offers[*prev_offer_id as usize];
        //     // previous_offer.is_accepted = false;
        //     // emit!(OfferAccepted {
        //     //     offer_id: previous_offer.id,
        //     //     buyer_address: *ctx.accounts.user.to_account_info().key,
        //     //     is_accepted: false,
        //     // });
        // }

        offer.is_accepted = true;
        offer.updated_at = Clock::get().unwrap().unix_timestamp as u64;
        request.offer_ids.push(offer.id);
        request.locked_seller_id = offer.seller_id;
        request.sellers_price_quote = offer.price;
        request.lifecycle = RequestLifecycle::AcceptedByBuyer;
        request.updated_at = Clock::get().unwrap().unix_timestamp as u64;

        emit!(RequestAccepted {
            request_id: request.id,
            offer_id: offer.id,
            seller_id: offer.seller_id,
            updated_at: request.updated_at,
            sellers_price_quote: request.sellers_price_quote,
        });

        emit!(OfferAccepted {
            offer_id: offer.id,
            buyer_address: *ctx.accounts.user.to_account_info().key,
            is_accepted: true,
        });

        Ok(())
    }


#[account]
pub struct Offer {
    pub authority: Pubkey,
    pub id: u64,
    pub request_id: u64,
    pub price: i64,
    pub images: Vec<String>,
    pub store_name: String,
    pub seller_id: u64,
    pub is_accepted: bool,
    pub created_at: u64,
    pub updated_at: u64,
}


#[account]
pub struct Request {
    pub authority: Pubkey,
    pub id: u64,
    pub name: String,
    pub buyer_id: u64,
    pub description: String,
    pub images: Vec<String>,
    pub sellers_price_quote: i64,
    pub seller_ids: Vec<u64>,
    pub offer_ids: Vec<u64>,
    pub locked_seller_id: u64,
    pub location: Location,
    pub created_at: u64,
    pub updated_at: u64,
    pub lifecycle: RequestLifecycle,
}

#[account]
#[derive(Debug)]
pub struct User {
    pub id: u64,
    pub username: String,
    pub phone: String,
    pub location: Location,
    pub created_at: i64,
    pub updated_at: i64,
    pub account_type: AccountType,
    pub authority: Pubkey,
}

1 Answer 1

1

The error proc-macro panicked: Invariant violation: composite constraints can only be raw or literals talks about the limitation of the Anchor framework.

As of now (I believe with current Anchor version 0.30.*) it's not possible to use/link the Rust constant in the #account macro to be part of the seeds.

    #[account(
        mut,
        seeds = [USER_TAG,authority.key().as_ref()],
        bump,
        has_one = authority
    )]

instead, you need to "hard code" (and possibly duplicate) the seed string into the macro directly

seeds = [b"user-tag", authority.key().as_ref()],

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.