@@ -1248,6 +1248,138 @@ func (s *IntegrationTestSuite) TestMsgBorrow() {
12481248 }
12491249}
12501250
1251+ func (s * IntegrationTestSuite ) TestMsgMaxBorrow () {
1252+ type testCase struct {
1253+ msg string
1254+ addr sdk.AccAddress
1255+ coin sdk.Coin
1256+ err error
1257+ }
1258+
1259+ app , ctx , srv , require := s .app , s .ctx , s .msgSrvr , s .Require ()
1260+
1261+ // create and fund a supplier which supplies 100 UMEE and 100 ATOM
1262+ supplier := s .newAccount (coin (umeeDenom , 100_000000 ), coin (atomDenom , 100_000000 ))
1263+ s .supply (supplier , coin (umeeDenom , 100_000000 ), coin (atomDenom , 100_000000 ))
1264+
1265+ // create a borrower which supplies and collateralizes 100 ATOM
1266+ borrower := s .newAccount (coin (atomDenom , 100_000000 ))
1267+ s .supply (borrower , coin (atomDenom , 100_000000 ))
1268+ s .collateralize (borrower , coin ("u/" + atomDenom , 100_000000 ))
1269+
1270+ // create an additional supplier (DUMP, PUMP tokens)
1271+ surplus := s .newAccount (coin (dumpDenom , 100_000000 ), coin (pumpDenom , 100_000000 ))
1272+ s .supply (surplus , coin (pumpDenom , 100_000000 ))
1273+ s .supply (surplus , coin (dumpDenom , 100_000000 ))
1274+
1275+ // this will be a DUMP (historic price 1.00, current price 0.50) borrower
1276+ // using PUMP (historic price 1.00, current price 2.00) collateral
1277+ dumpborrower := s .newAccount (coin (pumpDenom , 100_000000 ))
1278+ s .supply (dumpborrower , coin (pumpDenom , 100_000000 ))
1279+ s .collateralize (dumpborrower , coin ("u/" + pumpDenom , 100_000000 ))
1280+ // collateral value is $200 (current) or $100 (historic)
1281+ // collateral weights are always 0.25 in testing
1282+
1283+ // this will be a PUMP (historic price 1.00, current price 2.00) borrower
1284+ // using DUMP (historic price 1.00, current price 0.50) collateral
1285+ pumpborrower := s .newAccount (coin (dumpDenom , 100_000000 ))
1286+ s .supply (pumpborrower , coin (dumpDenom , 100_000000 ))
1287+ s .collateralize (pumpborrower , coin ("u/" + dumpDenom , 100_000000 ))
1288+ // collateral value is $50 (current) or $100 (historic)
1289+ // collateral weights are always 0.25 in testing
1290+
1291+ tcs := []testCase {
1292+ {
1293+ "uToken" ,
1294+ borrower ,
1295+ coin ("u/" + umeeDenom , 0 ),
1296+ types .ErrUToken ,
1297+ },
1298+ {
1299+ "unregistered token" ,
1300+ borrower ,
1301+ coin ("abcd" , 0 ),
1302+ types .ErrNotRegisteredToken ,
1303+ },
1304+ {
1305+ "zero collateral" ,
1306+ supplier ,
1307+ coin (atomDenom , 0 ),
1308+ types .ErrMaxBorrowZero ,
1309+ },
1310+ {
1311+ "atom borrow" ,
1312+ borrower ,
1313+ coin (atomDenom , 25_000000 ),
1314+ nil ,
1315+ },
1316+ {
1317+ "already borrowed max" ,
1318+ borrower ,
1319+ coin (atomDenom , 0 ),
1320+ types .ErrMaxBorrowZero ,
1321+ },
1322+ {
1323+ "dump borrower" ,
1324+ dumpborrower ,
1325+ coin (dumpDenom , 25_000000 ),
1326+ nil ,
1327+ },
1328+ {
1329+ "pump borrower" ,
1330+ pumpborrower ,
1331+ coin (pumpDenom , 6_250000 ),
1332+ nil ,
1333+ },
1334+ }
1335+
1336+ for _ , tc := range tcs {
1337+ msg := & types.MsgMaxBorrow {
1338+ Borrower : tc .addr .String (),
1339+ Denom : tc .coin .Denom ,
1340+ }
1341+ if tc .err != nil {
1342+ _ , err := srv .MaxBorrow (ctx , msg )
1343+ require .ErrorIs (err , tc .err , tc .msg )
1344+ } else {
1345+ // initial state
1346+ iBalance := app .BankKeeper .GetAllBalances (ctx , tc .addr )
1347+ iCollateral := app .LeverageKeeper .GetBorrowerCollateral (ctx , tc .addr )
1348+ iUTokenSupply := app .LeverageKeeper .GetAllUTokenSupply (ctx )
1349+ iExchangeRate := app .LeverageKeeper .DeriveExchangeRate (ctx , tc .coin .Denom )
1350+ iBorrowed := app .LeverageKeeper .GetBorrowerBorrows (ctx , tc .addr )
1351+
1352+ // verify the output of borrow function
1353+ resp , err := srv .MaxBorrow (ctx , msg )
1354+ require .NoError (err , tc .msg )
1355+ require .Equal (& types.MsgMaxBorrowResponse {
1356+ Borrowed : tc .coin ,
1357+ }, resp , tc .msg )
1358+
1359+ // final state
1360+ fBalance := app .BankKeeper .GetAllBalances (ctx , tc .addr )
1361+ fCollateral := app .LeverageKeeper .GetBorrowerCollateral (ctx , tc .addr )
1362+ fUTokenSupply := app .LeverageKeeper .GetAllUTokenSupply (ctx )
1363+ fExchangeRate := app .LeverageKeeper .DeriveExchangeRate (ctx , tc .coin .Denom )
1364+ fBorrowed := app .LeverageKeeper .GetBorrowerBorrows (ctx , tc .addr )
1365+
1366+ // verify token balance is increased by expected amount
1367+ require .Equal (iBalance .Add (tc .coin ), fBalance , tc .msg , "balances" )
1368+ // verify uToken collateral unchanged
1369+ require .Equal (iCollateral , fCollateral , tc .msg , "collateral" )
1370+ // verify uToken supply is unchanged
1371+ require .Equal (iUTokenSupply , fUTokenSupply , tc .msg , "uToken supply" )
1372+ // verify uToken exchange rate is unchanged
1373+ require .Equal (iExchangeRate , fExchangeRate , tc .msg , "uToken exchange rate" )
1374+ // verify borrowed coins increased by expected amount
1375+ require .Equal (iBorrowed .Add (tc .coin ), fBorrowed , "borrowed coins" )
1376+
1377+ // check all available invariants
1378+ s .checkInvariants (tc .msg )
1379+ }
1380+ }
1381+ }
1382+
12511383func (s * IntegrationTestSuite ) TestMsgRepay () {
12521384 type testCase struct {
12531385 msg string
0 commit comments