Skip to content

Commit 751e920

Browse files
committed
examples: test error cases
1 parent 1cef8a7 commit 751e920

2 files changed

Lines changed: 119 additions & 57 deletions

File tree

examples/12-bridge-and-invest-aave/tests/bridge.spec.ts

Lines changed: 56 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Chains, fp, OpType, randomEvmAddress } from '@mimicprotocol/sdk'
2-
import { Context, ContractCallMock, runTask, Swap } from '@mimicprotocol/test-ts'
2+
import { Context, ContractCallMock, Inputs, runTask, Swap } from '@mimicprotocol/test-ts'
33
import { expect } from 'chai'
44
import { AbiCoder, keccak256, toUtf8Bytes } from 'ethers'
55

@@ -47,41 +47,68 @@ describe('Bridge', () => {
4747
},
4848
]
4949

50-
it('produces the expected intents', async () => {
51-
const result = await runTask(taskDir, context, { inputs, calls })
52-
expect(result.success).to.be.true
53-
expect(result.timestamp).to.be.equal(context.timestamp)
50+
const itThrowsAnError = (inputs: Inputs, error: string): void => {
51+
it('throws an error', async () => {
52+
const result = await runTask(taskDir, context, { inputs, calls })
53+
expect(result.success).to.be.false
54+
expect(result.intents).to.have.lengthOf(0)
5455

55-
const intents = result.intents as Swap[]
56-
expect(intents).to.have.lengthOf(1)
56+
expect(result.logs).to.have.lengthOf(1)
57+
expect(result.logs[0]).to.include(error)
58+
})
59+
}
60+
61+
describe('when the chains are supported', () => {
62+
describe('when the chains are different', () => {
63+
it('produces the expected intents', async () => {
64+
const result = await runTask(taskDir, context, { inputs, calls })
65+
expect(result.success).to.be.true
66+
expect(result.timestamp).to.be.equal(context.timestamp)
67+
68+
const intents = result.intents as Swap[]
69+
expect(intents).to.have.lengthOf(1)
70+
71+
expect(intents[0].op).to.be.equal(OpType.Swap)
72+
expect(intents[0].settler).to.be.equal(context.settlers?.[0].address)
73+
expect(intents[0].user).to.be.equal(inputs.smartAccount)
74+
expect(intents[0].sourceChain).to.be.equal(sourceChain)
75+
expect(intents[0].destinationChain).to.be.equal(destinationChain)
5776

58-
expect(intents[0].op).to.be.equal(OpType.Swap)
59-
expect(intents[0].settler).to.be.equal(context.settlers?.[0].address)
60-
expect(intents[0].user).to.be.equal(inputs.smartAccount)
61-
expect(intents[0].sourceChain).to.be.equal(sourceChain)
62-
expect(intents[0].destinationChain).to.be.equal(destinationChain)
77+
const amount = fp(inputs.amount, decimals).toString()
78+
expect(intents[0].tokensIn).to.have.lengthOf(1)
79+
expect(intents[0].tokensIn[0].token).to.be.equal(arbitrumUsdc)
80+
expect(intents[0].tokensIn[0].amount).to.be.equal(amount)
6381

64-
const amount = fp(inputs.amount, decimals).toString()
65-
expect(intents[0].tokensIn).to.have.lengthOf(1)
66-
expect(intents[0].tokensIn[0].token).to.be.equal(arbitrumUsdc)
67-
expect(intents[0].tokensIn[0].amount).to.be.equal(amount)
82+
const minAmountOut = fp(inputs.minAmountOut, decimals).toString()
83+
expect(intents[0].tokensOut).to.have.lengthOf(1)
84+
expect(intents[0].tokensOut[0].token).to.be.equal(optimismUsdc)
85+
expect(intents[0].tokensOut[0].minAmount).to.be.equal(minAmountOut)
86+
expect(intents[0].tokensOut[0].recipient).to.be.equal(inputs.smartAccount)
6887

69-
const minAmountOut = fp(inputs.minAmountOut, decimals).toString()
70-
expect(intents[0].tokensOut).to.have.lengthOf(1)
71-
expect(intents[0].tokensOut[0].token).to.be.equal(optimismUsdc)
72-
expect(intents[0].tokensOut[0].minAmount).to.be.equal(minAmountOut)
73-
expect(intents[0].tokensOut[0].recipient).to.be.equal(inputs.smartAccount)
88+
expect(intents[0].maxFees).to.have.lengthOf(1)
89+
expect(intents[0].maxFees[0].token).to.be.equal(inputs.feeToken)
90+
expect(intents[0].maxFees[0].amount).to.be.equal(fp(inputs.maxFee, decimals).toString())
7491

75-
expect(intents[0].maxFees).to.have.lengthOf(1)
76-
expect(intents[0].maxFees[0].token).to.be.equal(inputs.feeToken)
77-
expect(intents[0].maxFees[0].amount).to.be.equal(fp(inputs.maxFee, decimals).toString())
92+
expect(intents[0].events).to.have.lengthOf(1)
7893

79-
expect(intents[0].events).to.have.lengthOf(1)
94+
const topic = keccak256(toUtf8Bytes('Bridged USDC'))
95+
expect(intents[0].events[0].topic).to.be.equal(topic)
96+
97+
const data = AbiCoder.defaultAbiCoder().encode(['address'], [optimismUsdc])
98+
expect(intents[0].events[0].data).to.be.equal(data)
99+
})
100+
})
101+
102+
describe('when the chains are the same', () => {
103+
const inputsSameChain = { ...inputs, destinationChain: inputs.sourceChain }
104+
105+
itThrowsAnError(inputsSameChain, 'Single-chain swap not supported')
106+
})
107+
})
80108

81-
const topic = keccak256(toUtf8Bytes('Bridged USDC'))
82-
expect(intents[0].events[0].topic).to.be.equal(topic)
109+
describe('when the chains are not supported', () => {
110+
const inputsUnsupportedChain = { ...inputs, destinationChain: Chains.Mainnet }
83111

84-
const data = AbiCoder.defaultAbiCoder().encode(['address'], [optimismUsdc])
85-
expect(intents[0].events[0].data).to.be.equal(data)
112+
itThrowsAnError(inputsUnsupportedChain, 'Invalid chain')
86113
})
87114
})

examples/12-bridge-and-invest-aave/tests/invest.spec.ts

Lines changed: 63 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
randomSig,
99
TriggerType,
1010
} from '@mimicprotocol/sdk'
11-
import { Call, Context, ContractCallMock, runTask } from '@mimicprotocol/test-ts'
11+
import { Call, Context, ContractCallMock, Inputs, runTask } from '@mimicprotocol/test-ts'
1212
import { expect } from 'chai'
1313
import { AbiCoder, concat } from 'ethers'
1414

@@ -65,41 +65,76 @@ describe('Invest', () => {
6565
},
6666
]
6767

68-
it('produces the expected intents', async () => {
69-
const result = await runTask(taskDir, context, { inputs, calls })
70-
expect(result.success).to.be.true
71-
expect(result.timestamp).to.be.equal(context.timestamp)
68+
const itThrowsAnError = (context: Context, inputs: Inputs, error: string): void => {
69+
it('throws an error', async () => {
70+
const result = await runTask(taskDir, context, { inputs, calls })
71+
expect(result.success).to.be.false
72+
expect(result.intents).to.have.lengthOf(0)
7273

73-
const intents = result.intents as Call[]
74-
expect(intents).to.have.lengthOf(1)
74+
expect(result.logs).to.have.lengthOf(1)
75+
expect(result.logs[0]).to.include(error)
76+
})
77+
}
78+
79+
describe('when the chain is supported', () => {
80+
describe('when the trigger is event', () => {
81+
describe('when the event user is the smart account', () => {
82+
it('produces the expected intents', async () => {
83+
const result = await runTask(taskDir, context, { inputs, calls })
84+
expect(result.success).to.be.true
85+
expect(result.timestamp).to.be.equal(context.timestamp)
86+
87+
const intents = result.intents as Call[]
88+
expect(intents).to.have.lengthOf(1)
89+
90+
expect(intents[0].op).to.be.equal(OpType.EvmCall)
91+
expect(intents[0].settler).to.be.equal(context.settlers?.[0].address)
92+
expect(intents[0].user).to.be.equal(inputs.smartAccount)
93+
expect(intents[0].chainId).to.be.equal(inputs.chainId)
94+
95+
expect(intents[0].maxFees).to.have.lengthOf(1)
96+
expect(intents[0].maxFees[0].token).to.be.equal(inputs.feeToken)
97+
expect(intents[0].maxFees[0].amount).to.be.equal(fp(inputs.maxFee, decimals).toString())
7598

76-
expect(intents[0].op).to.be.equal(OpType.EvmCall)
77-
expect(intents[0].settler).to.be.equal(context.settlers?.[0].address)
78-
expect(intents[0].user).to.be.equal(inputs.smartAccount)
79-
expect(intents[0].chainId).to.be.equal(inputs.chainId)
99+
expect(intents[0].calls).to.have.lengthOf(2)
80100

81-
expect(intents[0].maxFees).to.have.lengthOf(1)
82-
expect(intents[0].maxFees[0].token).to.be.equal(inputs.feeToken)
83-
expect(intents[0].maxFees[0].amount).to.be.equal(fp(inputs.maxFee, decimals).toString())
101+
const firstCall = intents[0].calls[0]
102+
expect(firstCall.target).to.be.equal(USDC)
103+
expect(firstCall.value).to.be.equal('0')
84104

85-
expect(intents[0].calls).to.have.lengthOf(2)
105+
const approveData = AbiCoder.defaultAbiCoder().encode(['address', 'uint256'], [aavePool, amount])
106+
expect(firstCall.data).to.be.equal(concat(['0x095ea7b3', approveData])) // approve
86107

87-
const firstCall = intents[0].calls[0]
88-
expect(firstCall.target).to.be.equal(USDC)
89-
expect(firstCall.value).to.be.equal('0')
108+
const secondCall = intents[0].calls[1]
109+
expect(secondCall.target).to.be.equal(aavePool)
110+
expect(secondCall.value).to.be.equal('0')
90111

91-
const approveData = AbiCoder.defaultAbiCoder().encode(['address', 'uint256'], [aavePool, amount])
92-
expect(firstCall.data).to.be.equal(concat(['0x095ea7b3', approveData])) // approve
112+
const supplyData = AbiCoder.defaultAbiCoder().encode(
113+
['address', 'uint256', 'address', 'uint16'],
114+
[USDC, amount, smartAccount, 0]
115+
)
116+
expect(secondCall.data).to.be.equal(concat(['0x617ba037', supplyData])) // supply
117+
})
118+
})
119+
120+
describe('when the event user is not the smart account', () => {
121+
const inputsOtherSmartAccount = { ...inputs, smartAccount: randomEvmAddress() }
122+
123+
itThrowsAnError(context, inputsOtherSmartAccount, 'Intent user not smart account')
124+
})
125+
})
126+
127+
describe('when the trigger is not event', () => {
128+
const cronContext = { ...context, trigger: { ...trigger, type: TriggerType.Cron } }
129+
130+
itThrowsAnError(cronContext, inputs, 'Trigger not event')
131+
})
132+
})
93133

94-
const secondCall = intents[0].calls[1]
95-
expect(secondCall.target).to.be.equal(aavePool)
96-
expect(secondCall.value).to.be.equal('0')
134+
describe('when the chain is not supported', () => {
135+
const inputsUnsupportedChain = { ...inputs, chainId: Chains.Mainnet }
97136

98-
const supplyData = AbiCoder.defaultAbiCoder().encode(
99-
['address', 'uint256', 'address', 'uint16'],
100-
[USDC, amount, smartAccount, 0]
101-
)
102-
expect(secondCall.data).to.be.equal(concat(['0x617ba037', supplyData])) // supply
137+
itThrowsAnError(context, inputsUnsupportedChain, 'Invalid chain')
103138
})
104139
})
105140

0 commit comments

Comments
 (0)