Skip to content

Commit 66cd123

Browse files
Osmosis migration (#5262)
2 parents 08f6489 + 4cbbb72 commit 66cd123

File tree

4 files changed

+180
-7
lines changed

4 files changed

+180
-7
lines changed

cosmwasm/cosmwasm.nix

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,9 +262,9 @@ _: {
262262
private_key = ''"$(op item get deployer --vault union-testnet-10 --field cosmos-private-key --reveal)"'';
263263
gas_config = {
264264
type = "fixed";
265-
gas_price = "0.005";
265+
gas_price = "0.01";
266266
gas_denom = "uosmo";
267-
gas_multiplier = "1.1";
267+
gas_multiplier = "1.2";
268268
max_gas = 60000000;
269269
};
270270
apps = {

deployments/deployments.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -642,8 +642,8 @@
642642
"core": {
643643
"address": "osmo1hnuj8f6d3wy3fcprt55vddv7v2650t6uudnvd2hukqrteeam8wjqata4fx",
644644
"height": 39452782,
645-
"commit": "cd4759ddf0dbc5b42aad19aaf26839d3dfd021f7",
646-
"code_id": 1719
645+
"commit": "2a03eb41a66a06f863663e450e7e648f816c978d",
646+
"code_id": 1849
647647
},
648648
"lightclient": {
649649
"cometbls": {
@@ -669,8 +669,8 @@
669669
"ucs03": {
670670
"address": "osmo1336jj8ertl8h7rdvnz4dh5rqahd09cy0x43guhsxx6xyrztx292qs2uecc",
671671
"height": 39452974,
672-
"commit": "6f21166bb1afe0620cc95644d9f9a511bd6ad6ac",
673-
"code_id": 1718,
672+
"commit": "2a03eb41a66a06f863663e450e7e648f816c978d",
673+
"code_id": 1848,
674674
"minter": {
675675
"type": "osmosis_tokenfactory",
676676
"address": "osmo12r3yc76u9lxe33yemstatnw8602culdjzrtr8lmnpycmd3z7d4jsxx60kc",

evm/contracts/CrosschainVault.sol

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import
88
"@openzeppelin-upgradeable/contracts/access/manager/AccessManagedUpgradeable.sol";
99
import
1010
"@openzeppelin-upgradeable/contracts/token/ERC20/extensions/ERC4626Upgradeable.sol";
11+
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
1112

1213
import "solady/utils/LibBytes.sol";
1314

@@ -25,6 +26,7 @@ contract CrosschainVault is
2526
{
2627
using LibBytes for *;
2728
using Math for *;
29+
using SafeERC20 for *;
2830

2931
uint256 public constant BPS_SCALE = 1_000_000;
3032

@@ -207,7 +209,7 @@ contract CrosschainVault is
207209
if (counterparty.debt < amount) {
208210
revert CrosschainVault_RepayingTooMuch();
209211
}
210-
IERC20(asset()).transferFrom(msg.sender, address(this), amount);
212+
IERC20(asset()).safeTransferFrom(msg.sender, address(this), amount);
211213
counterparty.debt -= amount;
212214
$.deployedCapital -= amount;
213215
}

evm/tests/src/05-app/CrosschainVault.t.sol

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,177 @@ contract CrosschainVaultDebtTest is CrosschainVaultTestBase {
566566
);
567567
vault.repay(DEFAULT_PATH, DEFAULT_CHANNEL_ID, BASE_TOKEN, 100001);
568568
}
569+
570+
function testRepayFullDebt() public {
571+
_setupCounterparty();
572+
_fundVault(10000000);
573+
574+
TokenOrderV2 memory order = _createTokenOrder(1000000, 985000);
575+
IBCPacket memory packet = _createPacket();
576+
577+
vm.prank(address(zkgm));
578+
vault.solve(packet, order, DEFAULT_PATH, address(0), RELAYER, "", false);
579+
580+
uint256 debt = vault.fungibleCounterparty(
581+
DEFAULT_PATH, DEFAULT_CHANNEL_ID, BASE_TOKEN
582+
).debt;
583+
assertEq(debt, 1000000, "Initial debt should be 1000000");
584+
585+
quoteToken.mint(REPAYER, debt);
586+
587+
vm.startPrank(REPAYER);
588+
quoteToken.approve(address(vault), debt);
589+
vault.repay(DEFAULT_PATH, DEFAULT_CHANNEL_ID, BASE_TOKEN, debt);
590+
vm.stopPrank();
591+
592+
assertEq(
593+
vault.fungibleCounterparty(
594+
DEFAULT_PATH, DEFAULT_CHANNEL_ID, BASE_TOKEN
595+
).debt,
596+
0,
597+
"Debt should be fully repaid"
598+
);
599+
assertEq(
600+
vault.deployedCapital(),
601+
0,
602+
"Deployed capital should be zero after full repayment"
603+
);
604+
}
605+
606+
function testRepayExactDebtAmount() public {
607+
_setupCounterparty();
608+
_fundVault(10000000);
609+
610+
TokenOrderV2 memory order = _createTokenOrder(1000000, 985000);
611+
IBCPacket memory packet = _createPacket();
612+
613+
vm.prank(address(zkgm));
614+
vault.solve(packet, order, DEFAULT_PATH, address(0), RELAYER, "", false);
615+
616+
uint256 repayAmount = 1000000;
617+
quoteToken.mint(REPAYER, repayAmount);
618+
619+
uint256 vaultBalanceBefore = quoteToken.balanceOf(address(vault));
620+
uint256 repayerBalanceBefore = quoteToken.balanceOf(REPAYER);
621+
622+
vm.startPrank(REPAYER);
623+
quoteToken.approve(address(vault), repayAmount);
624+
vault.repay(DEFAULT_PATH, DEFAULT_CHANNEL_ID, BASE_TOKEN, repayAmount);
625+
vm.stopPrank();
626+
627+
assertEq(
628+
quoteToken.balanceOf(address(vault)),
629+
vaultBalanceBefore + repayAmount,
630+
"Vault should receive exact repayment amount"
631+
);
632+
assertEq(
633+
quoteToken.balanceOf(REPAYER),
634+
repayerBalanceBefore - repayAmount,
635+
"Repayer should send exact repayment amount"
636+
);
637+
assertEq(
638+
vault.fungibleCounterparty(
639+
DEFAULT_PATH, DEFAULT_CHANNEL_ID, BASE_TOKEN
640+
).debt,
641+
0,
642+
"Debt should be zero"
643+
);
644+
}
645+
646+
function testRepayMultipleConsecutivePayments() public {
647+
_setupCounterparty();
648+
_fundVault(10000000);
649+
650+
TokenOrderV2 memory order = _createTokenOrder(1000000, 985000);
651+
IBCPacket memory packet = _createPacket();
652+
653+
vm.prank(address(zkgm));
654+
vault.solve(packet, order, DEFAULT_PATH, address(0), RELAYER, "", false);
655+
656+
uint256 totalDebt = 1000000;
657+
uint256 firstPayment = 300000;
658+
uint256 secondPayment = 400000;
659+
uint256 thirdPayment = 300000;
660+
661+
quoteToken.mint(REPAYER, totalDebt);
662+
663+
// First repayment
664+
vm.startPrank(REPAYER);
665+
quoteToken.approve(address(vault), firstPayment);
666+
vault.repay(DEFAULT_PATH, DEFAULT_CHANNEL_ID, BASE_TOKEN, firstPayment);
667+
assertEq(
668+
vault.fungibleCounterparty(
669+
DEFAULT_PATH, DEFAULT_CHANNEL_ID, BASE_TOKEN
670+
).debt,
671+
700000,
672+
"Debt after first payment"
673+
);
674+
675+
// Second repayment
676+
quoteToken.approve(address(vault), secondPayment);
677+
vault.repay(DEFAULT_PATH, DEFAULT_CHANNEL_ID, BASE_TOKEN, secondPayment);
678+
assertEq(
679+
vault.fungibleCounterparty(
680+
DEFAULT_PATH, DEFAULT_CHANNEL_ID, BASE_TOKEN
681+
).debt,
682+
300000,
683+
"Debt after second payment"
684+
);
685+
686+
// Third repayment
687+
quoteToken.approve(address(vault), thirdPayment);
688+
vault.repay(DEFAULT_PATH, DEFAULT_CHANNEL_ID, BASE_TOKEN, thirdPayment);
689+
assertEq(
690+
vault.fungibleCounterparty(
691+
DEFAULT_PATH, DEFAULT_CHANNEL_ID, BASE_TOKEN
692+
).debt,
693+
0,
694+
"Debt should be fully repaid after three payments"
695+
);
696+
vm.stopPrank();
697+
}
698+
699+
function testRepayRevertInsufficientApproval() public {
700+
_setupCounterparty();
701+
_fundVault(10000000);
702+
703+
TokenOrderV2 memory order = _createTokenOrder(1000000, 985000);
704+
IBCPacket memory packet = _createPacket();
705+
706+
vm.prank(address(zkgm));
707+
vault.solve(packet, order, DEFAULT_PATH, address(0), RELAYER, "", false);
708+
709+
uint256 repayAmount = 500000;
710+
quoteToken.mint(REPAYER, repayAmount);
711+
712+
vm.startPrank(REPAYER);
713+
// Approve less than the repayment amount
714+
quoteToken.approve(address(vault), repayAmount - 1);
715+
vm.expectRevert();
716+
vault.repay(DEFAULT_PATH, DEFAULT_CHANNEL_ID, BASE_TOKEN, repayAmount);
717+
vm.stopPrank();
718+
}
719+
720+
function testRepayRevertInsufficientBalance() public {
721+
_setupCounterparty();
722+
_fundVault(10000000);
723+
724+
TokenOrderV2 memory order = _createTokenOrder(1000000, 985000);
725+
IBCPacket memory packet = _createPacket();
726+
727+
vm.prank(address(zkgm));
728+
vault.solve(packet, order, DEFAULT_PATH, address(0), RELAYER, "", false);
729+
730+
uint256 repayAmount = 500000;
731+
// Only mint half of what's needed
732+
quoteToken.mint(REPAYER, repayAmount / 2);
733+
734+
vm.startPrank(REPAYER);
735+
quoteToken.approve(address(vault), repayAmount);
736+
vm.expectRevert();
737+
vault.repay(DEFAULT_PATH, DEFAULT_CHANNEL_ID, BASE_TOKEN, repayAmount);
738+
vm.stopPrank();
739+
}
569740
}
570741

571742
contract CrosschainVaultERC4626Test is CrosschainVaultTestBase {

0 commit comments

Comments
 (0)