Skip to content

Commit

Permalink
Test decode token pair factory contract
Browse files Browse the repository at this point in the history
  • Loading branch information
h0ngcha0 committed Feb 6, 2024
1 parent 5c7bc45 commit 12c8bc1
Show file tree
Hide file tree
Showing 2 changed files with 205 additions and 6 deletions.
201 changes: 200 additions & 1 deletion packages/web3/src/codec/contract-codec.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,34 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
import { web3 } from '@alephium/web3'
import { Method } from './method-codec'
import { contractCodec } from './contract-codec'
import { LoadImmField, Return } from './instr-codec'
import {
ApproveAlph,
AssertWithErrorCode,
BoolAnd,
ByteVecConcat,
ByteVecNeq,
CallLocal,
CopyCreateSubContractWithToken,
Encode,
I256Const0,
IfFalse,
LoadImmField,
LoadLocal,
LoadMutField,
Log5,
Return,
StoreLocal,
StoreMutField,
TokenRemaining,
U256Add,
U256Const,
U256Const0,
U256Const1,
U256From32Byte,
U256Gt,
U256Lt,
U256SHL
} from './instr-codec'

describe('Encode & decode contract', function () {
beforeAll(() => {
Expand Down Expand Up @@ -87,6 +114,178 @@ describe('Encode & decode contract', function () {
}
]
)

await testContractCode(
`
Contract TokenPairFactory(
pairTemplateId: ByteVec,
mut pairSize: U256
) {
event PairCreated(token0: ByteVec, token1: ByteVec, pair: ByteVec, currentPairSize: U256)
enum ErrorCodes {
ReserveOverflow = 0
InsufficientInitLiquidity = 1
InsufficientLiquidityMinted = 2
InsufficientLiquidityBurned = 3
InvalidToAddress = 4
InsufficientLiquidity = 5
InvalidTokenInId = 6
InvalidCalleeId = 7
InvalidK = 8
InsufficientOutputAmount = 9
InsufficientInputAmount = 10
IdenticalTokenIds = 11
Expired = 12
InsufficientToken0Amount = 13
InsufficientToken1Amount = 14
TokenNotExist = 15
}
fn sortTokens(tokenA: ByteVec, tokenB: ByteVec) -> (ByteVec, ByteVec) {
let left = u256From32Byte!(tokenA)
let right = u256From32Byte!(tokenB)
if (left < right) {
return tokenA, tokenB
}
return tokenB, tokenA
}
@using(preapprovedAssets = true, updateFields = true)
pub fn createPair(
payer: Address,
alphAmount: U256,
tokenAId: ByteVec,
tokenBId: ByteVec
) -> () {
assert!(
tokenRemaining!(payer, tokenAId) > 0 &&
tokenRemaining!(payer, tokenBId) > 0,
ErrorCodes.TokenNotExist
)
assert!(tokenAId != tokenBId, ErrorCodes.IdenticalTokenIds)
let (token0Id, token1Id) = sortTokens(tokenAId, tokenBId)
let encodedImmutableFields = encodeToByteVec!(token0Id, token1Id)
let encodedMutableFields = encodeToByteVec!(
0, // reserve0
0, // reserve1
0, // blockTimeStampLast
0, // price0CumulativeLast
0, // price1CumulativeLast
0 // totalSupply
)
let pairId = copyCreateSubContractWithToken!{payer -> ALPH: alphAmount}(
token0Id ++ token1Id,
pairTemplateId,
encodedImmutableFields,
encodedMutableFields,
1 << 255
)
emit PairCreated(token0Id, token1Id, pairId, pairSize)
pairSize = pairSize + 1
}
}
`,
[
{
isPublic: false,
assetModifier: 0,
argsLength: 2,
localsLength: 4,
returnLength: 2,
instrs: [
LoadLocal(0),
U256From32Byte,
StoreLocal(2),
LoadLocal(1),
U256From32Byte,
StoreLocal(3),
LoadLocal(2),
LoadLocal(3),
U256Lt,
IfFalse({ mode: 3, rest: Buffer.from([]) }),
LoadLocal(0),
LoadLocal(1),
Return,
LoadLocal(1),
LoadLocal(0),
Return
]
},
{
isPublic: true,
assetModifier: 3,
argsLength: 4,
localsLength: 9,
returnLength: 0,
instrs: [
LoadLocal(0),
LoadLocal(2),
TokenRemaining,
U256Const0,
U256Gt,
LoadLocal(0),
LoadLocal(3),
TokenRemaining,
U256Const0,
U256Gt,
BoolAnd,
U256Const({ mode: 15, rest: Buffer.from([]) }),
AssertWithErrorCode,
LoadLocal(2),
LoadLocal(3),
ByteVecNeq,
U256Const({ mode: 11, rest: Buffer.from([]) }),
AssertWithErrorCode,
LoadLocal(2),
LoadLocal(3),
CallLocal(0),
StoreLocal(5),
StoreLocal(4),
LoadLocal(4),
LoadLocal(5),
U256Const({ mode: 2, rest: Buffer.from([]) }),
Encode,
StoreLocal(6),
U256Const0,
U256Const0,
U256Const0,
U256Const0,
U256Const0,
U256Const0,
U256Const({ mode: 6, rest: Buffer.from([]) }),
Encode,
StoreLocal(7),
LoadLocal(0),
LoadLocal(1),
ApproveAlph,
LoadLocal(4),
LoadLocal(5),
ByteVecConcat,
LoadImmField(0),
LoadLocal(6),
LoadLocal(7),
U256Const1,
U256Const({ mode: 64, rest: Buffer.from([255]) }),
U256SHL,
CopyCreateSubContractWithToken,
StoreLocal(8),
I256Const0,
LoadLocal(4),
LoadLocal(5),
LoadLocal(8),
LoadMutField(0),
Log5,
LoadMutField(0),
U256Const1,
U256Add,
StoreMutField(0)
]
}
]
)
})

async function testContractCode(contractCode: string, methods: Method[]) {
Expand Down
10 changes: 5 additions & 5 deletions packages/web3/src/codec/instr-codec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ export const U256Const2: Instr = { code: 0x0e, value: {} }
export const U256Const3: Instr = { code: 0x0f, value: {} }
export const U256Const4: Instr = { code: 0x10, value: {} }
export const U256Const5: Instr = { code: 0x11, value: {} }
export const I256Const = (value: DecodedCompactInt): Instr => ({ code: 0x12, value })
export const U256Const = (value: DecodedCompactInt): Instr => ({ code: 0x13, value })
export const ByteConst = (value: ByteString): Instr => ({ code: 0x14, value })
export const AddressConst = (value: LockupScript): Instr => ({ code: 0x15, value })
export const I256Const = (value: DecodedCompactInt): Instr => ({ code: 0x12, value: { value } })
export const U256Const = (value: DecodedCompactInt): Instr => ({ code: 0x13, value: { value } })
export const ByteConst = (value: ByteString): Instr => ({ code: 0x14, value: { value } })
export const AddressConst = (value: LockupScript): Instr => ({ code: 0x15, value: { value } })
export const LoadLocal = (index: number): Instr => ({ code: 0x16, value: { index } })
export const StoreLocal = (index: number): Instr => ({ code: 0x17, value: { index } })
export const Pop: Instr = { code: 0x18, value: {} }
Expand Down Expand Up @@ -123,7 +123,7 @@ export const IsAssetAddress: Instr = { code: 0x48, value: {} }
export const IsContractAddress: Instr = { code: 0x49, value: {} }
export const Jump = (value: DecodedCompactInt): Instr => ({ code: 0x4a, value })
export const IfTrue = (value: DecodedCompactInt): Instr => ({ code: 0x4b, value })
export const IfFalse = (value: DecodedCompactInt): Instr => ({ code: 0x4c, value })
export const IfFalse = (value: DecodedCompactInt): Instr => ({ code: 0x4c, value: { value } })
export const Assert: Instr = { code: 0x4d, value: {} }
export const Blake2b: Instr = { code: 0x4e, value: {} }
export const Keccak256: Instr = { code: 0x4f, value: {} }
Expand Down

0 comments on commit 12c8bc1

Please sign in to comment.