Skip to content

Commit d024803

Browse files
Resolve conflicts, add mock oracles to tests
2 parents cc6e88c + cbbb126 commit d024803

File tree

21 files changed

+902
-164
lines changed

21 files changed

+902
-164
lines changed

MetaLamp/lending-pool/README.md

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,54 @@
1-
# Plutus Platform starter project
1+
# Lending Pool
22

3-
This project gives a simple starter project for using the Plutus Platform.
3+
Lending Pool is a smart contract application on Plutus Platform.
4+
The smart contract protocol is based on [Aave](https://aave.com/), but does not strictly follow it.
45

56
## Setting up
67

78
- Install nix
89
- Clone https://github.com/input-output-hk/plutus
910
- Set up your machine to build things with Nix, following the Plutus README (make sure to set up the binary cache!)
1011

11-
## The Plutus Application Backend (PAB) example
12+
## The Plutus Application Backend (PAB) usage
1213

13-
We have provided an example PAB application in `./pab`. With the PAB we can serve and interact
14-
with contracts over a web API. You can read more about the PAB here: [PAB Architecture](https://github.com/input-output-hk/plutus/blob/master/plutus-pab/ARCHITECTURE.adoc).
14+
We have provided two PAB applications in `./pab` and `./pab-simulation`. The first one is made for real world usage and interaction through frontend [client](client/README.md), the second one is a big test scenario.
15+
With the PAB we can serve and interact with contracts over a web API. You can read more about the PAB here: [PAB Architecture](https://github.com/input-output-hk/plutus/blob/master/plutus-pab/ARCHITECTURE.adoc).
1516

1617
1. Enter the nix shell (cd to the cloned Plutus repo):
1718

1819
```
19-
git checkout 58bf9ed626d498c140c69a859a508da03843d097
20+
git checkout 5cdd2c3d708bf4c33514681dee096da6463273b7
2021
nix-shell
2122
```
2223

23-
2. Build the PAB executable (cd to plutus-use-cases/MetaLamp/lending-pool):
24+
2. Build the PAB executables (cd to plutus-use-cases/MetaLamp/lending-pool):
2425

2526
```
26-
cabal build
27+
cabal build all
2728
```
2829

2930
3. Run the PAB binary:
3031

3132
```
32-
cabal run plutus-starter-pab
33-
````
33+
cabal run pab
34+
```
3435

3536
This will then start up the server on port 8080.
37+
38+
4. To run test simulation do:
39+
40+
```
41+
cabal run pab-simulation
42+
```
43+
44+
## Client
45+
46+
See the client [readme](client/README.md).
47+
48+
## Troubleshooting
49+
50+
See [note](client/README.md/#Troubleshooting).
51+
52+
## Protocol functionality
53+
54+
See the description of user endpoints [here](src/Plutus/Contracts/Endpoints.hs)
Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,51 @@
1-
# lending pool client
1+
# Lending pool client
2+
3+
The client application has a minimalistic interface to the PAB [server](/MetaLamp/lending-pool/README.md).
24

35
## Running the project
46

7+
1. Install npm packages.
8+
59
```
610
npm install
711
```
812

13+
2. Generate necessary PureScript code from Haskell source. This step runs an executable(`generate-purs`) from `lending-pool` directory, which requires a certain environment. The setup steps are described in `lending-pool/README`. Provided that you are able to build the backend, you can use the same approach to run purescript generation from `client` folder, i.e.
14+
15+
Enter the nix shell (cd to the cloned Plutus repo):
16+
17+
```
18+
git checkout 5cdd2c3d708bf4c33514681dee096da6463273b7
19+
nix-shell
20+
```
21+
22+
cd to `lending-pool/client` folder and execute
23+
24+
```
25+
npm run generate-purs
26+
```
27+
28+
3. Start the client:
29+
930
```
1031
npm start
1132
```
1233

13-
CORS protection needs to be disabled. You can use this script to launch chrome:
34+
4. Open browser to interact with the app at https://localhost:8009/.
35+
CORS protection needs to be disabled. You can use this script to launch chromium (note that first you need to close chromium completely, otherwise security won't be disabled):
1436

1537
```
1638
npm run start-chrome
1739
```
40+
41+
## Troubleshooting
42+
43+
Sometimes the build results in error with Haskell IDE enabled. If the build does not work or the app behaves strangely, disable IDE and clean all source files:
44+
45+
```
46+
cd MetaLamp/lending-pool/ && cabal clean
47+
```
48+
49+
```
50+
cd MetaLamp/lending-pool/client && rm -rf node_modules/ generated/ output/ plutus-purs/ .spago/
51+
```

MetaLamp/lending-pool/client/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
"purs:compile": "spago build",
1010
"docs": "spago docs",
1111
"repl": "spago repl",
12-
"generate-purs": "sh ./scripts/generate-purs.sh",
1312
"fetch-plutus-purs": "sh ./scripts/fetch-plutus-purs.sh",
13+
"generate-purs-only": "sh ./scripts/generate-purs.sh",
14+
"generate-purs": "npm run fetch-plutus-purs && npm run generate-purs-only",
1415
"start-chrome": "sh ./scripts/start-chrome.sh",
15-
"preinstall": "npm run fetch-plutus-purs && npm run generate-purs",
1616
"start": "npm run purs:compile && npm run webpack:server"
1717
},
1818
"dependencies": {

MetaLamp/lending-pool/client/src/Business/AaveUser.purs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import Capability.PollContract (class PollContract, PollError)
77
import Data.Either (Either)
88
import Data.Maybe (Maybe)
99
import Data.Newtype (class Newtype, unwrap)
10-
import Plutus.Contracts.Endpoints (BorrowParams, DepositParams, RepayParams, WithdrawParams, _Borrowed, _Deposited, _GetPubKey, _GetPubKeyBalance, _Repaid, _Withdrawn)
10+
import Plutus.Contracts.Endpoints (BorrowParams, ProvideCollateralParams, RevokeCollateralParams, DepositParams, RepayParams, WithdrawParams, _Borrowed, _Deposited, _GetPubKey, _GetPubKeyBalance, _Repaid, _Withdrawn, _CollateralProvided, _CollateralRevoked)
1111
import Plutus.PAB.Simulation (AaveContracts, _AaveUser)
1212
import Plutus.PAB.Webserver.Types (ContractInstanceClientState)
1313
import Plutus.V1.Ledger.Crypto (PubKeyHash)
@@ -33,6 +33,12 @@ borrow = getAaveResponseWith (Endpoint "borrow") _Borrowed <<< unwrap
3333
repay :: forall m. PollContract m => UserContractId -> RepayParams -> m (Either PollError Unit)
3434
repay = getAaveResponseWith (Endpoint "repay") _Repaid <<< unwrap
3535

36+
provideCollateral :: forall m. PollContract m => UserContractId -> ProvideCollateralParams -> m (Either PollError Unit)
37+
provideCollateral = getAaveResponseWith (Endpoint "provideCollateral") _CollateralProvided <<< unwrap
38+
39+
revokeCollateral :: forall m. PollContract m => UserContractId -> RevokeCollateralParams -> m (Either PollError Unit)
40+
revokeCollateral = getAaveResponseWith (Endpoint "revokeCollateral") _CollateralRevoked <<< unwrap
41+
3642
ownPubKey :: forall m. PollContract m => UserContractId -> m (Either PollError PubKeyHash)
3743
ownPubKey cid = getAaveResponseWith (Endpoint "ownPubKey") _GetPubKey (unwrap cid) ContractUnit
3844

MetaLamp/lending-pool/client/src/Component/Contract.purs

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import Halogen as H
2424
import Halogen.HTML as HH
2525
import Network.RemoteData (RemoteData(..))
2626
import Network.RemoteData as RD
27-
import Plutus.Contracts.Endpoints (BorrowParams(..), DepositParams(..), RepayParams(..), WithdrawParams(..))
27+
import Plutus.Contracts.Endpoints (BorrowParams(..), DepositParams(..), RepayParams(..), WithdrawParams(..), ProvideCollateralParams(..), RevokeCollateralParams(..))
2828
import Plutus.V1.Ledger.Crypto (PubKeyHash)
2929
import Plutus.V1.Ledger.Value (AssetClass(..), TokenName(..), Value)
3030
import View.FundsTable (fundsTable)
@@ -38,6 +38,8 @@ type State
3838
, withdraw :: RemoteData String Unit
3939
, borrow :: RemoteData String Unit
4040
, repay :: RemoteData String Unit
41+
, provideCollateral :: RemoteData String Unit
42+
, revokeCollateral :: RemoteData String Unit
4143
, submit :: RemoteData String Unit
4244
}
4345

@@ -53,6 +55,12 @@ _borrow = prop (SProxy :: SProxy "borrow")
5355
_repay :: Lens' State (RemoteData String Unit)
5456
_repay = prop (SProxy :: SProxy "repay")
5557

58+
_provideCollateral :: Lens' State (RemoteData String Unit)
59+
_provideCollateral = prop (SProxy :: SProxy "provideCollateral")
60+
61+
_revokeCollateral :: Lens' State (RemoteData String Unit)
62+
_revokeCollateral = prop (SProxy :: SProxy "revokeCollateral")
63+
5664
_submit :: Lens' State (RemoteData String Unit)
5765
_submit = prop (SProxy :: SProxy "submit")
5866

@@ -76,6 +84,8 @@ initialState { userFunds, userContractId, walletPubKey, reserves } =
7684
, deposit: NotAsked
7785
, borrow: NotAsked
7886
, repay: NotAsked
87+
, provideCollateral: NotAsked
88+
, revokeCollateral: NotAsked
7989
, submit: NotAsked
8090
}
8191

@@ -84,6 +94,8 @@ data Action
8494
| Withdraw { amount :: BigInteger, asset :: AssetClass }
8595
| Borrow { amount :: BigInteger, asset :: AssetClass }
8696
| Repay { amount :: BigInteger, asset :: AssetClass }
97+
| ProvideCollateral { amount :: BigInteger, asset :: AssetClass }
98+
| RevokeCollateral { amount :: BigInteger, asset :: AssetClass }
8799
| OnSubmitAmount SubmitOperation AmountForm.Output
88100

89101
-- potentially should be separate actions - just a convenience for now, while they are identical
@@ -92,6 +104,8 @@ data SubmitOperation
92104
| SubmitWithdraw
93105
| SubmitBorrow
94106
| SubmitRepay
107+
| SubmitProvideCollateral
108+
| SubmitRevokeCollateral
95109

96110
derive instance genericSubmitOperation :: Generic SubmitOperation _
97111

@@ -141,6 +155,18 @@ component =
141155
{ userContractId, walletPubKey } <- lift H.get
142156
lift (AaveUser.repay userContractId $ RepayParams { rpAmount: amount, rpAsset: asset, rpOnBehalfOf: walletPubKey })
143157
>>= either (throwError <<< show) (const <<< lift <<< H.raise $ SubmitSuccess)
158+
ProvideCollateral { amount, asset } ->
159+
runRD _provideCollateral <<< runExceptT
160+
$ do
161+
{ userContractId, walletPubKey } <- lift H.get
162+
lift (AaveUser.provideCollateral userContractId $ ProvideCollateralParams { pcpUnderlyingAsset: asset, pcpAmount: amount, pcpOnBehalfOf: walletPubKey })
163+
>>= either (throwError <<< show) (const <<< lift <<< H.raise $ SubmitSuccess)
164+
RevokeCollateral { amount, asset } ->
165+
runRD _revokeCollateral <<< runExceptT
166+
$ do
167+
{ userContractId, walletPubKey } <- lift H.get
168+
lift (AaveUser.revokeCollateral userContractId $ RevokeCollateralParams { rcpUnderlyingAsset: asset, rcpAmount: amount, rcpOnBehalfOf: walletPubKey })
169+
>>= either (throwError <<< show) (const <<< lift <<< H.raise $ SubmitSuccess)
144170
OnSubmitAmount operation (AmountForm.Submit { name, amount }) ->
145171
runRD _submit <<< runExceptT
146172
$ do
@@ -175,6 +201,20 @@ component =
175201
(throwError $ "Submit repay failed: " <> show repay)
176202
(const <<< pure $ unit)
177203
repay
204+
SubmitProvideCollateral -> do
205+
lift $ handleAction (ProvideCollateral { amount, asset })
206+
{ provideCollateral } <- lift H.get
207+
RD.maybe
208+
(throwError $ "Submit provideCollateral failed: " <> show provideCollateral)
209+
(const <<< pure $ unit)
210+
provideCollateral
211+
SubmitRevokeCollateral -> do
212+
lift $ handleAction (RevokeCollateral { amount, asset })
213+
{ revokeCollateral } <- lift H.get
214+
RD.maybe
215+
(throwError $ "Submit revokeCollateral failed: " <> show revokeCollateral)
216+
(const <<< pure $ unit)
217+
revokeCollateral
178218
Nothing -> throwError "Asset name not found"
179219

180220
render :: State -> H.ComponentHTML Action Slots m
@@ -194,7 +234,7 @@ component =
194234
, HH.slot _amountForm index AmountForm.component (reservesToAmounts state.reserves) (Just <<< (OnSubmitAmount operation))
195235
]
196236
)
197-
[ Tuple "Deposit" SubmitDeposit, Tuple "Withdraw" SubmitWithdraw, Tuple "Borrow" SubmitBorrow, Tuple "Repay" SubmitRepay ]
237+
[ Tuple "Deposit" SubmitDeposit, Tuple "Withdraw" SubmitWithdraw, Tuple "Borrow" SubmitBorrow, Tuple "Repay" SubmitRepay, Tuple "ProvideCollateral" SubmitProvideCollateral, Tuple "RevokeCollateral" SubmitRevokeCollateral ]
198238
]
199239

200240
reservesToAmounts :: Array { amount :: BigInteger, asset :: AssetClass } -> Array AmountForm.AmountInfo

MetaLamp/lending-pool/client/src/View/UsersTable.purs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ poolUsers asset users =
1818
]
1919

2020
userInfo :: forall props act. Tuple String UserConfig -> HH.HTML props act
21-
userInfo (Tuple userId (UserConfig { ucDebt, ucUsingAsCollateral })) =
21+
userInfo (Tuple userId (UserConfig { ucDebt, ucCollateralizedInvestment })) =
2222
HH.div_
2323
[ HH.div_ [ HH.text $ "User " <> userId ]
24-
, HH.div_ [ HH.text $ "Debt: " <> (show <<< fromMaybe (fromInt 0) $ ucDebt) ]
25-
, HH.div_ [ HH.text $ "Using as collateral: " <> (show ucUsingAsCollateral) ]
24+
, HH.div_ [ HH.text $ "Debt: " <> (show ucDebt) ]
25+
, HH.div_ [ HH.text $ "Collateral: " <> (show ucCollateralizedInvestment) ]
2626
]

MetaLamp/lending-pool/generate-purs/AaveTypes.hs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import Language.PureScript.Bridge.TypeParameters (A, E)
3131
import qualified PSGenerator.Common
3232
import qualified Plutus.Contracts.Core as Aave
3333
import qualified Plutus.Contracts.Endpoints as Aave
34+
import qualified Plutus.Contracts.Oracle as Oracle
3435
import Plutus.PAB.Simulation (AaveContracts (..))
3536
import Plutus.V1.Ledger.Value (AssetClass)
3637

@@ -48,6 +49,7 @@ psRatio = expand <$> psTypeParameters
4849
aaveTypes :: [SumType 'Haskell]
4950
aaveTypes = [ (equal <*> (genericShow <*> mkSumType)) (Proxy @AaveContracts)
5051
, (equal <*> (genericShow <*> mkSumType)) (Proxy @Aave.Aave)
52+
, (equal <*> (genericShow <*> mkSumType)) (Proxy @Oracle.Oracle)
5153
, (equal <*> (genericShow <*> mkSumType)) (Proxy @(Aave.ContractResponse E A))
5254
, (equal <*> (genericShow <*> mkSumType)) (Proxy @Aave.CreateParams)
5355
, (order <*> (equal <*> (genericShow <*> mkSumType))) (Proxy @AssetClass)
@@ -58,4 +60,6 @@ aaveTypes = [ (equal <*> (genericShow <*> mkSumType)) (Proxy @AaveContracts)
5860
, (equal <*> (genericShow <*> mkSumType)) (Proxy @Aave.DepositParams)
5961
, (equal <*> (genericShow <*> mkSumType)) (Proxy @Aave.WithdrawParams)
6062
, (equal <*> (genericShow <*> mkSumType)) (Proxy @Aave.BorrowParams)
61-
, (equal <*> (genericShow <*> mkSumType)) (Proxy @Aave.RepayParams) ]
63+
, (equal <*> (genericShow <*> mkSumType)) (Proxy @Aave.RepayParams)
64+
, (equal <*> (genericShow <*> mkSumType)) (Proxy @Aave.ProvideCollateralParams)
65+
, (equal <*> (genericShow <*> mkSumType)) (Proxy @Aave.RevokeCollateralParams) ]

MetaLamp/lending-pool/plutus-starter.cabal

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ maintainer: Your email
2323

2424
library
2525
exposed-modules:
26-
Plutus.Contracts.Endpoints Plutus.Contracts.FungibleToken Plutus.Contracts.AToken Plutus.Contracts.Core Plutus.Contracts.State Plutus.State.Select Plutus.State.Update Plutus.Contracts.TxUtils Plutus.OutputValue Ext.Plutus.Ledger.Contexts Plutus.PAB.Simulation
26+
Plutus.Contracts.Endpoints Plutus.Contracts.FungibleToken Plutus.Contracts.AToken Plutus.Contracts.Core Plutus.Contracts.Oracle Plutus.Contracts.State Plutus.State.Select Plutus.State.Update Plutus.Contracts.TxUtils Plutus.OutputValue Ext.Plutus.Ledger.Contexts Plutus.PAB.Simulation
2727
build-depends:
2828
base >= 4.9 && < 5,
2929
aeson,
@@ -102,7 +102,7 @@ test-suite test
102102
main-is: Main.hs
103103
hs-source-dirs: test
104104
other-modules:
105-
Spec.Start Spec.Deposit Spec.Withdraw Spec.Shared Utils.Data Utils.Trace Fixtures Fixtures.Aave Fixtures.Asset Fixtures.Init Fixtures.Wallet
105+
Spec.Start Spec.Deposit Spec.Withdraw Spec.Shared Utils.Data Utils.Trace Fixtures Fixtures.Policy Fixtures.Aave Fixtures.Asset Fixtures.Init Fixtures.Wallet
106106
default-language: Haskell2010
107107
ghc-options: -Wall -Wnoncanonical-monad-instances
108108
-Wincomplete-uni-patterns -Wincomplete-record-updates

MetaLamp/lending-pool/src/Ext/Plutus/Ledger/Contexts.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ findValueByDatumHash dh outs = mconcat $ mapMaybe f outs
3737
| otherwise = Nothing
3838

3939
{-# INLINABLE parseDatum #-}
40+
-- | Find datum inside pending transaction and parse it from data
4041
parseDatum :: PlutusTx.IsData a => TxInfo -> DatumHash -> Maybe a
4142
parseDatum txInfo dh = findDatum dh txInfo >>= (PlutusTx.fromData . getDatum)
4243

0 commit comments

Comments
 (0)