Skip to content

Commit

Permalink
Merge pull request #473 from rabbitholegg/mmackz/fabric/amount-zero
Browse files Browse the repository at this point in the history
fix(fabric): fix amount zero issue
  • Loading branch information
mmackz authored Aug 8, 2024
2 parents 10879aa + a373fde commit 9e81e1f
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 44 deletions.
5 changes: 5 additions & 0 deletions .changeset/short-roses-pull.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rabbitholegg/questdk-plugin-fabric": minor
---

fix amount zero issue
17 changes: 11 additions & 6 deletions packages/fabric/src/Fabric.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
Chains,
type MintIntentParams,
} from '@rabbitholegg/questdk-plugin-utils'
import { apply } from '@rabbitholegg/questdk/filter'
import { apply } from '@rabbitholegg/questdk'
import { type Address } from 'viem'
import { describe, expect, test } from 'vitest'

Expand All @@ -13,11 +13,11 @@ describe('Given the fabric plugin', () => {
describe('should return a valid action filter', () => {
test('when making a valid mint action', async () => {
const filter = await mint({
chainId: 1,
contractAddress: '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF',
chainId: 8453,
contractAddress: '0x2efc6064239121d1d7efb503355daa82b87ee89c',
})
expect(filter).toBeTypeOf('object')
expect(Number(filter.chainId)).toBe(1)
expect(Number(filter.chainId)).toBe(8453)
if (typeof filter.to === 'string') {
expect(filter.to).toMatch(/^0x[a-fA-F0-9]{40}$/)
} else {
Expand Down Expand Up @@ -57,8 +57,13 @@ describe('Given the fabric plugin', () => {
failingTestCases.forEach((testCase) => {
const { transaction, description, params } = testCase
test(description, async () => {
const filter = await mint(params)
expect(apply(transaction, filter)).to.be.false
try {
const filter = await mint(params)
const result = apply(transaction, filter)
expect(result).toBe(false)
} catch (error) {
expect(error).toBeInstanceOf(Error)
}
})
})
})
Expand Down
76 changes: 60 additions & 16 deletions packages/fabric/src/Fabric.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,60 @@
import { FABRIC_ABI } from './abi'
import { FABRIC_MINT_ABI, FABRIC_MINTFOR_ABI } from './abi'
import { getContractData } from './utils'
import {
type MintActionParams,
type TransactionFilter,
compressJson,
GreaterThanOrEqual,
} from '@rabbitholegg/questdk'
import {
Chains,
DEFAULT_ACCOUNT,
chainIdToViemChain,
getMintAmount,
type MintIntentParams,
} from '@rabbitholegg/questdk-plugin-utils'
import {
type Address,
type PublicClient,
type SimulateContractReturnType,
type TransactionRequest,
createPublicClient,
encodeFunctionData,
http,
zeroAddress,
} from 'viem'

export const mint = async (
mint: MintActionParams,
): Promise<TransactionFilter> => {
const { chainId, contractAddress, recipient } = mint
const { chainId, contractAddress, amount, recipient } = mint

const { minPurchaseSeconds, tps } = await getContractData(
chainId,
contractAddress,
)

if (minPurchaseSeconds == null || tps == null) {
throw new Error('Contract data not found')
}

const numTokens = minPurchaseSeconds * tps * getMintAmount(amount)

return compressJson({
chainId,
to: contractAddress,
input: {
$abi: FABRIC_ABI,
account: recipient,
$or: [
{
$abi: FABRIC_MINT_ABI,
numTokens: GreaterThanOrEqual(numTokens),
},
{
$abi: FABRIC_MINTFOR_ABI,
numTokens: GreaterThanOrEqual(numTokens),
account: recipient,
},
],
},
})
}
Expand All @@ -54,9 +80,13 @@ export const getFees = async (
throw new Error('ERC20 not supported')
}

const mintUnits = typeof amount === 'number' ? BigInt(amount) : BigInt(1)
if (!minPurchaseSeconds || !tps) {
throw new Error('Contract data not found')
}

const mintUnits = getMintAmount(amount)

const mintCost = (minPurchaseSeconds as bigint) * (tps as bigint) * mintUnits
const mintCost = minPurchaseSeconds * tps * mintUnits

return { actionFee: mintCost, projectFee: BigInt(0) }
}
Expand All @@ -75,10 +105,14 @@ export const getMintIntent = async (
throw new Error('ERC20 not supported')
}

const mintArgs = [(minPurchaseSeconds as bigint) * (tps as bigint) * amount]
if (!minPurchaseSeconds || !tps) {
throw new Error('Contract data not found')
}

const mintArgs = [minPurchaseSeconds * tps * getMintAmount(amount)]

const data = encodeFunctionData({
abi: FABRIC_ABI,
abi: FABRIC_MINT_ABI,
functionName: 'mint',
args: mintArgs,
})
Expand All @@ -98,25 +132,35 @@ export const simulateMint = async (
): Promise<SimulateContractReturnType> => {
const { chainId, contractAddress, amount } = mint

const _client =
client ??
createPublicClient({
chain: chainIdToViemChain(chainId),
transport: http(),
})

const from = account ?? DEFAULT_ACCOUNT
const {
erc20Address,
minPurchaseSeconds,
tps,
client: _client,
} = await getContractData(chainId, contractAddress, client)
const { erc20Address, minPurchaseSeconds, tps } = await getContractData(
chainId,
contractAddress,
client,
)

// fail simulation if erc20 is used
if (erc20Address !== zeroAddress) {
throw new Error('ERC20 not supported')
}

const mintArgs = [(minPurchaseSeconds as bigint) * (tps as bigint) * amount]
if (!minPurchaseSeconds || !tps) {
throw new Error('Contract data not found')
}

const mintArgs = [minPurchaseSeconds * tps * getMintAmount(amount)]

const result = await _client.simulateContract({
address: contractAddress,
value,
abi: FABRIC_ABI,
abi: FABRIC_MINT_ABI,
functionName: 'mint',
args: mintArgs,
account: from,
Expand Down
35 changes: 19 additions & 16 deletions packages/fabric/src/abi.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const FABRIC_ABI = [
export const FABRIC_MINT_ABI = [
{
inputs: [
{
Expand All @@ -15,40 +15,43 @@ export const FABRIC_ABI = [
{
inputs: [
{
internalType: 'address',
name: 'account',
type: 'address',
internalType: 'uint256',
name: 'numTokens',
type: 'uint256',
},
{
internalType: 'uint256',
name: 'numTokens',
name: 'referralCode',
type: 'uint256',
},
{
internalType: 'address',
name: 'referrer',
type: 'address',
},
],
name: 'mintFor',
name: 'mintWithReferral',
outputs: [],
stateMutability: 'payable',
type: 'function',
},
]

export const FABRIC_MINTFOR_ABI = [
{
inputs: [
{
internalType: 'uint256',
name: 'numTokens',
type: 'uint256',
internalType: 'address',
name: 'account',
type: 'address',
},
{
internalType: 'uint256',
name: 'referralCode',
name: 'numTokens',
type: 'uint256',
},
{
internalType: 'address',
name: 'referrer',
type: 'address',
},
],
name: 'mintWithReferral',
name: 'mintFor',
outputs: [],
stateMutability: 'payable',
type: 'function',
Expand Down
10 changes: 4 additions & 6 deletions packages/fabric/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import { type Address, type PublicClient, createPublicClient, http } from 'viem'

interface ContractData {
erc20Address: Address
minPurchaseSeconds: bigint
tps: bigint
client: PublicClient
minPurchaseSeconds: bigint | undefined
tps: bigint | undefined
}

export async function getContractData(
Expand Down Expand Up @@ -38,8 +37,7 @@ export async function getContractData(

return {
erc20Address: erc20Address as Address,
minPurchaseSeconds: minPurchaseSeconds as bigint,
tps: tps as bigint,
client: client as PublicClient,
minPurchaseSeconds: minPurchaseSeconds as bigint | undefined,
tps: tps as bigint | undefined,
}
}

0 comments on commit 9e81e1f

Please sign in to comment.