diff --git a/src/integration/blockchain/realunit/__tests__/realunit-blockchain.service.spec.ts b/src/integration/blockchain/realunit/__tests__/realunit-blockchain.service.spec.ts index ff3f2d4b03..451d88c577 100644 --- a/src/integration/blockchain/realunit/__tests__/realunit-blockchain.service.spec.ts +++ b/src/integration/blockchain/realunit/__tests__/realunit-blockchain.service.spec.ts @@ -90,42 +90,12 @@ describe('RealUnitBlockchainService', () => { }); describe('getBrokerbotSellPrice', () => { - it('should query BrokerBot contract and apply default 0.5% slippage', async () => { + it('should query BrokerBot contract and return exact amount', async () => { // BrokerBot returns 1000 ZCHF (in Wei) for 10 shares mockReadContract.mockResolvedValue(BigInt('1000000000000000000000')); const result = await service.getBrokerbotSellPrice(MOCK_BROKERBOT_ADDRESS, 10); - // 1000 ZCHF * (1 - 0.005) = 995 ZCHF - expect(result.zchfAmountWei).toBe(BigInt('995000000000000000000')); - }); - - it('should calculate correctly for 1 share', async () => { - // BrokerBot returns 100 ZCHF for 1 share - mockReadContract.mockResolvedValue(BigInt('100000000000000000000')); - - const result = await service.getBrokerbotSellPrice(MOCK_BROKERBOT_ADDRESS, 1); - - // 100 * 0.995 = 99.5 ZCHF - expect(result.zchfAmountWei).toBe(BigInt('99500000000000000000')); - }); - - it('should accept custom slippage in basis points', async () => { - // BrokerBot returns 1000 ZCHF for 10 shares - mockReadContract.mockResolvedValue(BigInt('1000000000000000000000')); - - const result = await service.getBrokerbotSellPrice(MOCK_BROKERBOT_ADDRESS, 10, 100); // 1% slippage - - // 1000 * (1 - 0.01) = 990 ZCHF - expect(result.zchfAmountWei).toBe(BigInt('990000000000000000000')); - }); - - it('should handle zero slippage', async () => { - mockReadContract.mockResolvedValue(BigInt('1000000000000000000000')); - - const result = await service.getBrokerbotSellPrice(MOCK_BROKERBOT_ADDRESS, 10, 0); - - // Full amount with no slippage expect(result.zchfAmountWei).toBe(BigInt('1000000000000000000000')); }); diff --git a/src/integration/blockchain/realunit/realunit-blockchain.service.ts b/src/integration/blockchain/realunit/realunit-blockchain.service.ts index 7dd5c13c79..82192d8b6f 100644 --- a/src/integration/blockchain/realunit/realunit-blockchain.service.ts +++ b/src/integration/blockchain/realunit/realunit-blockchain.service.ts @@ -130,11 +130,7 @@ export class RealUnitBlockchainService { }; } - async getBrokerbotSellPrice( - brokerbotAddress: string, - shares: number, - slippageBps = 50, - ): Promise<{ zchfAmountWei: bigint }> { + async getBrokerbotSellPrice(brokerbotAddress: string, shares: number): Promise<{ zchfAmountWei: bigint }> { const blockchain = [Environment.DEV, Environment.LOC].includes(GetConfig().environment) ? Blockchain.SEPOLIA : Blockchain.ETHEREUM; @@ -150,21 +146,17 @@ export class RealUnitBlockchainService { }); // Call getSellPrice on the BrokerBot contract - const sellPriceWei = (await publicClient.readContract({ + const zchfAmountWei = (await publicClient.readContract({ address: brokerbotAddress as `0x${string}`, abi: BROKERBOT_ABI, functionName: 'getSellPrice', args: [BigInt(shares)], } as any)) as bigint; - if (sellPriceWei === 0n) { + if (zchfAmountWei === 0n) { throw new Error('BrokerBot returned zero sell price'); } - // Apply slippage buffer (reduce expected amount to account for price movement) - const slippageFactor = BigInt(10000 - slippageBps); - const zchfAmountWei = (sellPriceWei * slippageFactor) / BigInt(10000); - return { zchfAmountWei }; } } diff --git a/src/subdomains/supporting/realunit/realunit.service.ts b/src/subdomains/supporting/realunit/realunit.service.ts index 2f0f270d09..5ceeb7c73e 100644 --- a/src/subdomains/supporting/realunit/realunit.service.ts +++ b/src/subdomains/supporting/realunit/realunit.service.ts @@ -980,7 +980,8 @@ export class RealUnitService { throw new BadRequestException('Delegation delegator does not match user address'); } - // Calculate expected ZCHF amount from BrokerBot (with slippage buffer) + // Calculate expected ZCHF amount from BrokerBot + // If price drops between quote and execution, transaction reverts safely and user can retry const [{ zchfAmountWei }, zchfAsset] = await Promise.all([ this.blockchainService.getBrokerbotSellPrice(this.getBrokerbotAddress(), Math.floor(request.amount)), this.getZchfAsset(),