Skip to content

Commit

Permalink
fix: sending transfer as fee returns amt to sender
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaelcr committed Aug 24, 2023
1 parent 66aa721 commit e23012a
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 11 deletions.
2 changes: 2 additions & 0 deletions src/admin-rpc/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export const AdminApi: FastifyPluginCallback<Record<never, never>, Server, TypeB
schema: {
description: 'Scan for BRC-20 operations within a block range',
querystring: Type.Object({
// TIP: The first BRC-20 token was deployed at height `779832`. This should be a good
// place to start.
start_block: Type.Integer(),
end_block: Type.Integer(),
}),
Expand Down
16 changes: 6 additions & 10 deletions src/pg/brc20/brc20-pg-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
DbBrc20ScannedInscription,
DbBrc20MintInsert,
DbBrc20DeployInsert,
DbBrc20TransferInsert,
} from './types';
import { Brc20Deploy, Brc20Mint, Brc20Transfer, brc20FromInscriptionContent } from './helpers';
import { hexToBuffer } from '../../api/util/helpers';
Expand Down Expand Up @@ -60,12 +61,7 @@ export class Brc20PgStore {
const block = await sql<DbBrc20ScannedInscription[]>`
SELECT
i.content,
(
CASE EXISTS(SELECT location_id FROM genesis_locations WHERE location_id = l.id)
WHEN TRUE THEN TRUE
ELSE FALSE
END
) AS genesis,
EXISTS(SELECT location_id FROM genesis_locations WHERE location_id = l.id) AS genesis,
${sql(LOCATIONS_COLUMNS.map(c => `l.${c}`))}
FROM locations AS l
INNER JOIN inscriptions AS i ON l.inscription_id = i.id
Expand Down Expand Up @@ -98,8 +94,7 @@ export class Brc20PgStore {
break;
}
}
}
if (!write.genesis) {
} else {
await this.applyTransfer(write);
}
}
Expand Down Expand Up @@ -257,7 +252,8 @@ export class Brc20PgStore {
inscription_id: transfer.inscription_id,
location_id: args.id,
brc20_deploy_id: transfer.brc20_deploy_id,
address: args.address,
// If a transfer is sent as fee, its amount must be returned to sender.
address: args.address ?? transfer.from_address,
avail_balance: amount.toString(),
trans_balance: '0',
type: DbBrc20BalanceTypeId.transferTo,
Expand Down Expand Up @@ -386,7 +382,7 @@ export class Brc20PgStore {
const available = new BigNumber(balanceRes[0].avail_balance);
if (transAmt.gt(available)) return;

const transferInsert = {
const transferInsert: DbBrc20TransferInsert = {
inscription_id: transfer.location.inscription_id,
brc20_deploy_id: balanceRes[0].brc20_deploy_id,
block_height: transfer.location.block_height,
Expand Down
12 changes: 11 additions & 1 deletion src/pg/brc20/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ export type DbBrc20Deploy = {
limit?: string;
};

export type DbBrc20TransferInsert = {
inscription_id: string;
brc20_deploy_id: string;
block_height: string;
tx_id: string;
from_address: string;
to_address: string | null;
amount: string;
};

export type DbBrc20Transfer = {
id: string;
inscription_id: string;
Expand Down Expand Up @@ -93,7 +103,7 @@ export type DbBrc20BalanceInsert = {
inscription_id: PgNumeric;
location_id: PgNumeric;
brc20_deploy_id: PgNumeric;
address: string | null;
address: string;
avail_balance: PgNumeric;
trans_balance: PgNumeric;
type: DbBrc20BalanceTypeId;
Expand Down
68 changes: 68 additions & 0 deletions tests/brc20.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1506,6 +1506,74 @@ describe('BRC-20', () => {
expect(prevBlockJson2.results[0]).toBeUndefined();
});

test('sending transfer as fee returns amount to sender', async () => {
const address = 'bc1p3cyx5e2hgh53w7kpxcvm8s4kkega9gv5wfw7c4qxsvxl0u8x834qf0u2td';
await deployAndMintPEPE(address);
await db.updateInscriptions(
new TestChainhookPayloadBuilder()
.apply()
.block({
height: 775619,
hash: '00000000000000000002b14f0c5dde0b2fc74d022e860696bd64f1f652756674',
})
.transaction({
hash: 'eee52b22397ea4a4aefe6a39931315e93a157091f5a994216c0aa9c8c6fef47a',
})
.inscriptionRevealed(
brc20Reveal({
json: {
p: 'brc-20',
op: 'transfer',
tick: 'PEPE',
amt: '9000',
},
number: 7,
tx_id: 'eee52b22397ea4a4aefe6a39931315e93a157091f5a994216c0aa9c8c6fef47a',
address: address,
})
)
.build()
);
await db.updateInscriptions(
new TestChainhookPayloadBuilder()
.apply()
.block({
height: 775620,
hash: '00000000000000000003feae13d107f0f2c4fb4dd08fb2a8b1ab553512e77f03',
})
.transaction({
hash: '7edaa48337a94da327b6262830505f116775a32db5ad4ad46e87ecea33f21bac',
})
.inscriptionTransferred({
inscription_id: 'eee52b22397ea4a4aefe6a39931315e93a157091f5a994216c0aa9c8c6fef47ai0',
updated_address: null, // Sent as fee
satpoint_pre_transfer:
'eee52b22397ea4a4aefe6a39931315e93a157091f5a994216c0aa9c8c6fef47a:0:0',
satpoint_post_transfer:
'7edaa48337a94da327b6262830505f116775a32db5ad4ad46e87ecea33f21bac:0:0',
post_transfer_output_value: null,
tx_index: 0,
})
.build()
);

const response1 = await fastify.inject({
method: 'GET',
url: `/ordinals/brc-20/balances/${address}`,
});
expect(response1.statusCode).toBe(200);
const json1 = response1.json();
expect(json1.total).toBe(1);
expect(json1.results).toStrictEqual([
{
available_balance: '10000',
overall_balance: '10000',
ticker: 'PEPE',
transferrable_balance: '0',
},
]);
});

test('cannot spend valid transfer twice', async () => {
const address = 'bc1p3cyx5e2hgh53w7kpxcvm8s4kkega9gv5wfw7c4qxsvxl0u8x834qf0u2td';
const address2 = '3QNjwPDRafjBm9XxJpshgk3ksMJh3TFxTU';
Expand Down

0 comments on commit e23012a

Please sign in to comment.