Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expect specific error messages in tests. #97

Merged
merged 1 commit into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 85 additions & 35 deletions FungibleToken.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
FungibleTokenAdmin,
FungibleTokenAdminBase,
FungibleTokenAdminDeployProps,
FungibleTokenErrors,
} from "./index.js"

const proofsEnabled = process.env.SKIP_PROOFS !== "true"
Expand Down Expand Up @@ -137,15 +138,17 @@ describe("token integration", async () => {
const burnAmount = UInt64.from(100)

it("should not mint before calling resume()", async () => {
await rejects(() =>
Mina.transaction({
await rejects(async () =>
await Mina.transaction({
sender: sender,
fee: 1e8,
}, async () => {
AccountUpdate.fundNewAccount(sender, 1)
await tokenAContract.mint(sender, mintAmount)
})
)
}), (err: Error) => {
if (err.message.includes(FungibleTokenErrors.tokenPaused)) return true
else return false
})
})
it("should accept a call to resume()", async () => {
const tx = await Mina.transaction({
Expand All @@ -158,7 +161,7 @@ describe("token integration", async () => {
await tx.prove()
await tx.send()
})
it("should mint for the sender account", async () => {
it("should mint for the sender and receiver account", async () => {
const initialBalance = (await tokenAContract.getBalanceOf(sender))
.toBigInt()
const initialCirculating = (await tokenAContract.getCirculating()).toBigInt()
Expand All @@ -175,13 +178,25 @@ describe("token integration", async () => {
await tx.prove()
await tx.send()

const tx2 = await Mina.transaction({
sender: sender,
fee: 1e8,
}, async () => {
AccountUpdate.fundNewAccount(sender, 1)
await tokenAContract.mint(receiver, mintAmount)
})

tx2.sign([sender.key, tokenAdmin.key])
await tx2.prove()
await tx2.send()

equal(
(await tokenAContract.getBalanceOf(sender)).toBigInt(),
initialBalance + mintAmount.toBigInt(),
)
equal(
(await tokenAContract.getCirculating()).toBigInt(),
initialCirculating + mintAmount.toBigInt(),
initialCirculating + mintAmount.mul(UInt64.from(2)).toBigInt(),
)
})

Expand Down Expand Up @@ -221,19 +236,26 @@ describe("token integration", async () => {

tx.sign([sender.key])
await tx.prove()
await rejects(() => tx.send())
await rejects(() => tx.send(), (err: Error) => {
if (err.message.includes("required authorization was not provided")) return true
else return false
})
})

it("should refuse to burn tokens without signature from the token holder", async () => {
const tx = await Mina.transaction({
sender: sender,
fee: 1e8,
}, async () => {
await tokenAContract.burn(sender, burnAmount)
await tokenAContract.burn(receiver, burnAmount)
})

tx.sign([sender.key])
await tx.prove()
await rejects(() => tx.send())
await rejects(() => tx.send(), (err: Error) => {
if (err.message.includes("Invalid signature on account_update 1")) return true
else return false
})
})

it("correctly changes the admin contract", async () => {
Expand Down Expand Up @@ -269,7 +291,10 @@ describe("token integration", async () => {
})
tx3.sign([sender.key, tokenAdmin.key])
await tx3.prove()
await rejects(() => tx3.send())
await rejects(() => tx3.send(), (err: Error) => {
if (err.message.includes("required authorization was not provided")) return true
else return false
})
})
})

Expand All @@ -287,7 +312,6 @@ describe("token integration", async () => {
sender: sender,
fee: 1e8,
}, async () => {
AccountUpdate.fundNewAccount(sender, 1)
await tokenAContract.transfer(
sender,
receiver,
Expand Down Expand Up @@ -318,10 +342,15 @@ describe("token integration", async () => {
sender: sender,
fee: 1e8,
}, async () => {
await tokenAContract.transfer(sender, receiver, sendAmount)
await tokenAContract.transfer(receiver, sender, sendAmount)
})

tx.sign([sender.key])
await tx.prove()
await rejects(() => tx.send())
await rejects(() => tx.send(), (err: Error) => {
if (err.message.includes("Invalid signature on account_update 1")) return true
else return false
})
})

it("should do a transaction constructed manually, approved by the token contract", async () => {
Expand Down Expand Up @@ -382,8 +411,10 @@ describe("token integration", async () => {
fee: 1e8,
}, async () => {
await tokenAContract.approveAccountUpdates([updateReceive, updateSend])
})
)
}), (err: Error) => {
if (err.message.includes(FungibleTokenErrors.flashMinting)) return true
else return false
})
})

it("should reject unbalanced transactions", async () => {
Expand All @@ -400,8 +431,10 @@ describe("token integration", async () => {
await rejects(() =>
Mina.transaction(deployer, async () => {
await tokenAContract.approveAccountUpdates([updateSend, updateReceive])
})
)
}), (err: Error) => {
if (err.message.includes(FungibleTokenErrors.flashMinting)) return true
else return false
})
})

it("rejects transactions with mismatched tokens", async () => {
Expand All @@ -423,7 +456,10 @@ describe("token integration", async () => {
AccountUpdate.fundNewAccount(sender, 1)
await tokenAContract.approveAccountUpdates([updateSend])
await tokenBContract.approveAccountUpdates([updateReceive])
})
}), (err: Error) => {
if (err.message.includes(FungibleTokenErrors.flashMinting)) return true
else return false
}
))
})

Expand All @@ -439,8 +475,10 @@ describe("token integration", async () => {
receiver,
sendAmount,
)
})
)
}), (err: Error) => {
if (err.message.includes(FungibleTokenErrors.noTransferFromCirculation)) return true
else return false
})
})

it("Should prevent transfers to account that's tracking circulation", async () => {
Expand All @@ -455,8 +493,10 @@ describe("token integration", async () => {
tokenA,
sendAmount,
)
})
)
}), (err: Error) => {
if (err.message.includes(FungibleTokenErrors.noTransferFromCirculation)) return true
else return false
})
})

it("Should reject manually constructed transfers from the account that's tracking circulation", async () => {
Expand All @@ -477,8 +517,10 @@ describe("token integration", async () => {
fee: 1e8,
}, async () => {
await tokenAContract.approveAccountUpdates([updateSend, updateReceive])
})
)
}), (err: Error) => {
if (err.message.includes(FungibleTokenErrors.noTransferFromCirculation)) return true
else return false
})
})

it("Should reject manually constructed transfers to the account that's tracking circulation", async () => {
Expand All @@ -499,8 +541,10 @@ describe("token integration", async () => {
fee: 1e8,
}, async () => {
await tokenAContract.approveAccountUpdates([updateSend, updateReceive])
})
)
}), (err: Error) => {
if (err.message.includes(FungibleTokenErrors.noTransferFromCirculation)) return true
else return false
})
})
})

Expand All @@ -519,8 +563,10 @@ describe("token integration", async () => {
fee: 1e8,
}, async () => {
await tokenAContract.approveBase(AccountUpdateForest.fromFlatArray([updateSend]))
})
)
}), (err: Error) => {
if (err.message.includes(FungibleTokenErrors.noPermissionChangeAllowed)) return true
else return false
})
})
})

Expand All @@ -539,14 +585,16 @@ describe("token integration", async () => {
await tx.send()
})
it("will block transactions while paused", async () => {
await rejects(() => (
await rejects(() =>
Mina.transaction({
sender: sender,
fee: 1e8,
}, async () => {
await tokenAContract.transfer(sender, receiver, sendAmount)
})
))
}), (err: Error) => {
if (err.message.includes(FungibleTokenErrors.tokenPaused)) return true
else return false
})
})
it("can be resumed by the admin", async () => {
const tx = await Mina.transaction({
Expand Down Expand Up @@ -681,8 +729,8 @@ describe("token integration", async () => {
})

it("should reject an unbalanced transaction", async () => {
const depositAmount = UInt64.from(10)
const withdrawAmount = UInt64.from(5)
const depositAmount = UInt64.from(5)
const withdrawAmount = UInt64.from(10)
const updateWithdraw = await thirdPartyAContract.withdraw(withdrawAmount)
const updateDeposit = await thirdPartyBContract.deposit(depositAmount)
updateDeposit.body.mayUseToken = AccountUpdate.MayUseToken.InheritFromParent
Expand All @@ -696,8 +744,10 @@ describe("token integration", async () => {
updateWithdraw,
updateDeposit,
]))
})
)
}), (err: Error) => {
if (err.message.includes(FungibleTokenErrors.unbalancedTransaction)) return true
else return false
})
})
})

Expand Down
2 changes: 1 addition & 1 deletion FungibleToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export const FungibleTokenErrors = {
noTransferFromCirculation: "Can't transfer to/from the circulation account",
noPermissionChangeAllowed: "Can't change permissions for access or receive on token accounts",
flashMinting:
"Flash-minting detected. Please make sure that your `AccountUpdate`s are ordered properly, so that tokens are not received before they are sent.",
"Flash-minting or unbalanced transaction detected. Please make sure that your transaction is balanced, and that your `AccountUpdate`s are ordered properly, so that tokens are not received before they are sent.",
unbalancedTransaction: "Transaction is unbalanced",
}

Expand Down