2

I created an auction with escrow. I succesfully create a campaign account, and can do the first bid. But I try a second bid, the program should send the previous bid back to the previous bidder. Every time I try this I get this error:

Proxy {logs: Array(4), programErrorStack: wt, stack: 'Error: failed to send transaction: Transaction sim…id (webpack-internal:///./pages/index.jsx:110:13)', message: 'failed to send transaction: Transaction simulation…alances before and after instruction do not match'}
[[Handler]]
: 
Object
[[Target]]
: 
Error: failed to send transaction: Transaction simulation failed: Error processing Instruction 0: sum of account balances before and after instruction do not match at Connection.sendEncodedTransaction (webpack-internal:///../node_modules/@solana/web3.js/lib/index.browser.esm.js:7362:13) at async Connection.sendRawTransaction (webpack-internal:///../node_modules/@solana/web3.js/lib/index.browser.esm.js:7319:20) at async ct (webpack-internal:///../node_modules/@project-serum/anchor/dist/browser/index.js:59:9950) at async st.sendAndConfirm (webpack-internal:///../node_modules/@project-serum/anchor/dist/browser/index.js:59:8673) at async Object.eval [as bid] (webpack-internal:///../node_modules/@project-serum/anchor/dist/browser/index.js:74:48251) at async bid (webpack-internal:///./pages/index.jsx:110:13)
[[IsRevoked]]
: 
false

This is my program:


use anchor_lang::prelude::*;
use anchor_lang::solana_program::entrypoint::ProgramResult;

declare_id!("9V9FcjfsbLV1LD3n7GrdScf1pNh9ReUiRiWK12JKQjDu");

#[program]
pub mod crowdfunding {
    use super::*;

     pub fn create(ctx: Context<Create>, name: String, description: String, minimum: u64, delta: u64) -> ProgramResult {
        let campaign = &mut ctx.accounts.campaign;
        campaign.name = name;
        campaign.description = description;
        campaign.highest_bid = minimum;
        campaign.minimum = minimum;
        campaign.delta = delta;
        campaign.highest_bidder = *ctx.accounts.user.key;
        campaign.admin = *ctx.accounts.user.key;
        Ok(())
     }

     pub fn close(ctx: Context<Close>) -> ProgramResult {
        let campaign = &mut ctx.accounts.campaign;
        let user = &mut ctx.accounts.user;
        if campaign.admin != *user.key {
            return Err(ProgramError::IllegalOwner);
        }
        let rent_balance = Rent::get()?.minimum_balance(campaign.to_account_info().data_len());
        if **campaign.to_account_info().lamports.borrow() - rent_balance < campaign.highest_bid {
            return Err(ProgramError::InsufficientFunds);
                     
        }
        **campaign.to_account_info().try_borrow_mut_lamports()? -= campaign.highest_bid;
        **user.to_account_info().try_borrow_mut_lamports()? += campaign.highest_bid;
        Ok(())
     }

     pub fn bid(ctx: Context<Bid>, amount: u64) -> ProgramResult {
        let campaign = &mut ctx.accounts.campaign;

        let old_bid =  &campaign.highest_bid;
        let old_bidcopy = &campaign.highest_bid;
        let old_bidder = &mut ctx.accounts.old_bidder;


             if amount < ( campaign.highest_bid + campaign.delta ) {
            return Err(ProgramError::InsufficientFunds);
        }

       if  campaign.highest_bidder != *old_bidder.key {
             return Err(ProgramError::IllegalOwner);
       }



        if campaign.admin != *old_bidder.key {

            let rent_balance = Rent::get()?.minimum_balance(campaign.to_account_info().data_len());
            if **campaign.to_account_info().lamports.borrow() - rent_balance < campaign.highest_bid {
            return Err(ProgramError::InsufficientFunds);
                     
        }
        **campaign.to_account_info().try_borrow_mut_lamports()? -= *old_bid;
        **old_bidder.to_account_info().try_borrow_mut_lamports()? += *old_bidcopy ;
          
        }


        let ix = anchor_lang::solana_program::system_instruction::transfer(
            &ctx.accounts.user.key(),
            &ctx.accounts.campaign.key(),
            amount
        );
        anchor_lang::solana_program::program::invoke(
            &ix,
            &[
                ctx.accounts.user.to_account_info(),
                ctx.accounts.campaign.to_account_info()
            ]
        );

        (&mut ctx.accounts.campaign).highest_bid = amount;
         (&mut ctx.accounts.campaign).highest_bidder = ctx.accounts.user.key();
        Ok(())
     }

}

#[derive(Accounts)] 
#[instruction(name: String)]
pub struct Create<'info> {
    #[account(init, 
        payer=user, 
        space=1000, 
        seeds=[
            user.key().as_ref(),
            b"_",
            name.as_ref()
    ], bump)]
    pub campaign: Account<'info, Campaign>,
    #[account(mut)]
    pub user: Signer<'info>,
    pub system_program: Program<'info, System>

}

#[derive(Accounts)] 
pub struct Close<'info> {
    #[account(mut)]
    pub campaign: Account<'info, Campaign>,
    #[account(mut)]
    pub user: Signer<'info>

}

#[derive(Accounts)] 
pub struct Bid<'info> {
    #[account(mut)]
    pub campaign: Account<'info, Campaign>,
    #[account(mut)]
    pub user: Signer<'info>,
    /// CHECK We check it with campaign data
    #[account(mut)]
    pub old_bidder: AccountInfo<'info>,
    pub system_program: Program<'info, System>
}

#[account]
pub struct Campaign {
    pub admin:  Pubkey,
    pub highest_bidder: Pubkey,
    name: String,
    description: String, 
    minimum: u64,
    delta: u64,
    highest_bid: u64
}

I was also wondering: Who will pay for this transaction (send the SOL back). It should be the new bidder... Thank you very much for your time!

1 Answer 1

1

The answer to this question solved it for me:

Error processing Instruction 0: sum of account balances before and after instruction do not match

In my case I had a function that had two shipments of balances. One through the system program with transfer and another through try_borrow_mut_lamports()?.

You have to put the transfer function first and then the try_borrow_mut_lamports() function

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.