diff --git a/README.md b/README.md
index 5e686096..5c6a7577 100755
--- a/README.md
+++ b/README.md
@@ -221,6 +221,7 @@ All the deployed contracts' addresses are available [here](../../wiki/Addresses)
 | [Melon](contracts/adapters/melon) | A protocol for decentralized on-chain asset management. | [Asset adapter](contracts/adapters/melon/MelonAssetAdapter.sol) | ["MelonToken"](./contracts/adapters/melon/MelonTokenAdapter.sol) |
 | [mStable](./contracts/adapters/mstable) | mStable unifies stablecoins, lending and swapping into one standard. | [Asset adapter](./contracts/adapters/mstable/MstableAssetAdapter.sol) 
 [Staking adapter](./contracts/adapters/mstable/MstableStakingAdapter.sol) | ["Masset"](./contracts/adapters/mstable/MstableTokenAdapter.sol) |
 | [Nexus Mutual](./contracts/adapters/nexus) | A people-powered alternative to insurance. | [Staking adapter](./contracts/adapters/nexus/NexusStakingAdapter.sol) | — |
+| [Pendle Finance](./contracts/adapters/pendle) | Trading future yield. | [Asset adapter](./contracts/adapters/pendle/PendleMarketAdapter.sol) 
 [Staking adapter](./contracts/adapters/pendle/PendleStakingAdapter.sol) | ["Pendle Market"](./contracts/adapters/pendle/PendleMarketTokenAdapter.sol) |
 | [Pickle Finance](./contracts/adapters/pickle) | Off peg bad, on peg good. | [Asset adapter](./contracts/adapters/pickle/PickleAssetAdapter.sol) 
 [Staking adapter V1](./contracts/adapters/pickle/PickleStakingV1Adapter.sol) 
 [Staking adapter V2](./contracts/adapters/pickle/PickleStakingV2Adapter.sol) | ["PickleJar"](./contracts/adapters/pickle/PickleTokenAdapter.sol) |
 | [PieDAO](./contracts/adapters/pieDAO) | The Asset Allocation DAO. | [Asset adapter](./contracts/adapters/pieDAO/PieDAOPieAdapter.sol) 
 [Staking adapter](./contracts/adapters/pieDAO/PieDAOStakingAdapter.sol) | ["PieDAO Pie Token"](./contracts/adapters/pieDAO/PieDAOPieTokenAdapter.sol) |
 | [PoolTogether](./contracts/adapters/poolTogether) | Decentralized no-loss lottery. Supports SAI, DAI, and USDC pools. | [Asset adapter](./contracts/adapters/poolTogether/PoolTogetherAdapter.sol) | ["PoolTogether pool"](./contracts/adapters/poolTogether/PoolTogetherTokenAdapter.sol) |
diff --git a/contracts/adapters/pendle/PendleMarketAdapter.sol b/contracts/adapters/pendle/PendleMarketAdapter.sol
new file mode 100755
index 00000000..cddf93b1
--- /dev/null
+++ b/contracts/adapters/pendle/PendleMarketAdapter.sol
@@ -0,0 +1,42 @@
+// Copyright (C) 2020 Zerion Inc. 
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+pragma solidity 0.6.5;
+pragma experimental ABIEncoderV2;
+
+import { ERC20 } from "../../ERC20.sol";
+import { ProtocolAdapter } from "../ProtocolAdapter.sol";
+
+/**
+ * @title Asset adapter for Pendle Finance (markets).
+ * @dev Implementation of ProtocolAdapter abstract contract.
+ * @author Anton Buenavista 
+ */
+contract PendleMarketAdapter is ProtocolAdapter {
+
+    string public constant override adapterType = "Asset";
+
+    string public constant override tokenType = "PendleMarket LP token";
+
+    /**
+     * @return Amount of Pendle Market LP tokens held by the given account.
+     * @param token Address of the Pendle Market.
+     * @param account Address of the user.
+     * @dev Implementation of ProtocolAdapter interface function.
+     */
+    function getBalance(address token, address account) public view override returns (uint256) {
+        return ERC20(token).balanceOf(account);
+    }
+}
diff --git a/contracts/adapters/pendle/PendleMarketTokenAdapter.sol b/contracts/adapters/pendle/PendleMarketTokenAdapter.sol
new file mode 100644
index 00000000..bb40f8de
--- /dev/null
+++ b/contracts/adapters/pendle/PendleMarketTokenAdapter.sol
@@ -0,0 +1,135 @@
+// Copyright (C) 2020 Zerion Inc. 
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+pragma solidity 0.6.5;
+pragma experimental ABIEncoderV2;
+
+import { ERC20 } from "../../ERC20.sol";
+import { TokenMetadata, Component } from "../../Structs.sol";
+import { TokenAdapter } from "../TokenAdapter.sol";
+
+
+/**
+ * @dev PendleMarket contract interface.
+ * Only the functions required for PendleTokenAdapter contract are added.
+ * The PendleMarket contract is available here
+ * github.com/pendle-finance/pendle-core/blob/master/contracts/interfaces/IPendleMarket.sol.
+ */
+interface PendleMarket {
+    function xyt() external view returns (address);
+    function token() external view returns (address);
+    function getReserves()
+        external
+        view
+        returns (
+            uint256 xytBalance,
+            uint256 xytWeight,
+            uint256 tokenBalance,
+            uint256 tokenWeight,
+            uint256 currentBlock
+        );
+}
+
+/**
+ * @title Token adapter for PendleMarket Tokens.
+ * @dev Implementation of TokenAdapter abstract contract.
+ * @author Anton Buenavista 
+ */
+contract PendleMarketTokenAdapter is TokenAdapter {
+
+    /**
+     * @return TokenMetadata struct with ERC20-style token info.
+     * @dev Implementation of TokenAdapter interface function.
+     */
+    function getMetadata(address token) external view override returns (TokenMetadata memory) {
+        return TokenMetadata({
+            token: token,
+            name: getMarketName(token),
+            symbol: ERC20(token).symbol(),
+            decimals: ERC20(token).decimals()
+        });
+    }
+
+    /**
+     * @return Array of Component structs with underlying tokens rates for the given token.
+     * @dev Implementation of TokenAdapter abstract contract function.
+     */
+    function getComponents(address market) external view override returns (Component[] memory) {
+        address token = PendleMarket(market).token();
+        address xyt = PendleMarket(market).xyt();
+        uint256 totalSupply = ERC20(market).totalSupply();
+        (uint256 xytBalance, ,uint256 tokenBalance, , ) = PendleMarket(market).getReserves();
+
+        Component[] memory components = new Component[](2);
+
+        components[0] = Component({
+            token: xyt,
+            tokenType: "ERC20",
+            rate: totalSupply == 0 ? 0 : xytBalance * 1e18 / totalSupply
+        });
+        components[1] = Component({
+            token: token,
+            tokenType: "ERC20",
+            rate: totalSupply == 0 ? 0 : tokenBalance * 1e18 / totalSupply
+        });
+
+        return components;
+    }
+
+    function getMarketName(address market) internal view returns (string memory) {
+        return string(
+            abi.encodePacked(
+                getSymbol(PendleMarket(market).xyt()),
+                "/",
+                getSymbol(PendleMarket(market).token()),
+                " Market"
+            )
+        );
+    }
+
+    function getSymbol(address token) internal view returns (string memory) {
+        (, bytes memory returnData) = token.staticcall(
+            abi.encodeWithSelector(ERC20(token).symbol.selector)
+        );
+
+        if (returnData.length == 32) {
+            return convertToString(abi.decode(returnData, (bytes32)));
+        } else {
+            return abi.decode(returnData, (string));
+        }
+    }
+
+    /**
+     * @dev Internal function to convert bytes32 to string and trim zeroes.
+     */
+    function convertToString(bytes32 data) internal pure returns (string memory) {
+        uint256 length = 0;
+        bytes memory result;
+
+        for (uint256 i = 0; i < 32; i++) {
+            if (data[i] != byte(0)) {
+                length++;
+            }
+        }
+
+        result = new bytes(length);
+
+        for (uint256 i = 0; i < length; i++) {
+            result[i] = data[i];
+        }
+
+        return string(result);
+    }
+}
diff --git a/contracts/adapters/pendle/PendleStakingAdapter.sol b/contracts/adapters/pendle/PendleStakingAdapter.sol
new file mode 100644
index 00000000..f1e3b642
--- /dev/null
+++ b/contracts/adapters/pendle/PendleStakingAdapter.sol
@@ -0,0 +1,53 @@
+// Copyright (C) 2020 Zerion Inc. 
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+pragma solidity 0.6.5;
+pragma experimental ABIEncoderV2;
+
+import { ProtocolAdapter } from "../ProtocolAdapter.sol";
+
+
+/**
+ * @dev Proxy contract interface for calculating liquidity mining rewards.
+ * Only the functions required for PendleStakingZerionProxy contract are added.
+ */
+interface PendleStakingZerionProxy {
+    function earned(address user) external view returns (uint256);
+}
+
+/**
+ * @title Adapter for Pendle Finance protocol.
+ * @dev Implementation of ProtocolAdapter interface.
+ * @author Anton Buenavista 
+ */
+contract PendleStakingAdapter is ProtocolAdapter {
+
+    string public constant override adapterType = "Asset";
+
+    string public constant override tokenType = "ERC20";
+
+    address internal constant PENDLE = 0x808507121B80c02388fAd14726482e061B8da827;
+    address internal constant STAKING_WRAPPER = 0x3cFfEd42e0BD6d45894283d90cF3F75e7CA55855;
+
+    /**
+     * @return Amount of PENDLE rewards after staking for a given account.
+     * @dev Implementation of ProtocolAdapter interface function.
+     */
+    function getBalance(address token, address account) external view override returns (uint256) {
+        if (token == PENDLE) {
+            return PendleStakingZerionProxy(STAKING_WRAPPER).earned(account);
+        }
+    }
+}
diff --git a/test/PendleMarketAdapter.js b/test/PendleMarketAdapter.js
new file mode 100755
index 00000000..103a9383
--- /dev/null
+++ b/test/PendleMarketAdapter.js
@@ -0,0 +1,99 @@
+import displayToken from './helpers/displayToken';
+
+const AdapterRegistry = artifacts.require('AdapterRegistry');
+const ProtocolAdapter = artifacts.require('PendleMarketAdapter');
+const TokenAdapter = artifacts.require('PendleMarketTokenAdapter');
+const ERC20TokenAdapter = artifacts.require('ERC20TokenAdapter');
+
+contract('PendleMarketTokenAdapter', () => {
+  const ytUSDCMarket = '0x8315BcBC2c5C1Ef09B71731ab3827b0808A2D6bD';
+  const ytUSDCAddress = '0xcDb5b940E95C8632dEcDc806B90dD3fC44E699fE';
+  const usdcAddress = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
+  // Random address with positive balances
+  const testAddress = '0x76A16d9325E9519Ef1819A4e7d16B168956f325F';
+
+  let accounts;
+  let adapterRegistry;
+  let protocolAdapterAddress;
+  let tokenAdapterAddress;
+  let erc20TokenAdapterAddress;
+  const PENDLE_LPT = [
+    ytUSDCMarket,
+    'YT-aUSDC-29DEC2022/USDC Market',
+    'PENDLE-LPT',
+    '18',
+  ];
+  const YT = [
+    ytUSDCAddress,
+    'YT Aave interest bearing USDC 29DEC2022',
+    'YT-aUSDC-29DEC2022',
+    '6',
+  ];
+  const USDC = [
+    usdcAddress,
+    'USD Coin',
+    'USDC',
+    '6',
+  ];
+
+  beforeEach(async () => {
+    accounts = await web3.eth.getAccounts();
+    await ProtocolAdapter.new({ from: accounts[0] })
+      .then((result) => {
+        protocolAdapterAddress = result.address;
+      });
+    await TokenAdapter.new({ from: accounts[0] })
+      .then((result) => {
+        tokenAdapterAddress = result.address;
+      });
+    await ERC20TokenAdapter.new({ from: accounts[0] })
+      .then((result) => {
+        erc20TokenAdapterAddress = result.address;
+      });
+    await AdapterRegistry.new({ from: accounts[0] })
+      .then((result) => {
+        adapterRegistry = result.contract;
+      });
+    await adapterRegistry.methods.addProtocols(
+      ['Pendle Market'],
+      [[
+        'Mock Protocol Name',
+        'Mock protocol description',
+        'Mock website',
+        'Mock icon',
+        '0',
+      ]],
+      [[
+        protocolAdapterAddress,
+      ]],
+      [[[
+        ytUSDCMarket,
+      ]]],
+    )
+      .send({
+        from: accounts[0],
+        gas: '1000000',
+      });
+    await adapterRegistry.methods.addTokenAdapters(
+      ['ERC20', 'PendleMarket LP token'],
+      [erc20TokenAdapterAddress, tokenAdapterAddress],
+    )
+      .send({
+        from: accounts[0],
+        gas: '1000000',
+      });
+  });
+
+  it('should return correct balances', async () => {
+    await adapterRegistry.methods['getBalances(address)'](testAddress)
+      .call()
+      .then((result) => {
+        displayToken(result[0].adapterBalances[0].balances[0].base);
+        displayToken(result[0].adapterBalances[0].balances[0].underlying[0]);
+        displayToken(result[0].adapterBalances[0].balances[0].underlying[1]);
+        assert.deepEqual(result[0].adapterBalances[0].balances[0].base.metadata, PENDLE_LPT);
+        assert.deepEqual(result[0].adapterBalances[0].balances[0].underlying[0].metadata, YT);
+        assert.deepEqual(result[0].adapterBalances[0].balances[0].underlying[1].metadata, USDC);
+      });
+  });
+});
diff --git a/test/PendleStakingAdapter.js b/test/PendleStakingAdapter.js
new file mode 100644
index 00000000..ae6ff10b
--- /dev/null
+++ b/test/PendleStakingAdapter.js
@@ -0,0 +1,68 @@
+import displayToken from './helpers/displayToken';
+
+const AdapterRegistry = artifacts.require('AdapterRegistry');
+const ProtocolAdapter = artifacts.require('PendleStakingAdapter');
+const ERC20TokenAdapter = artifacts.require('ERC20TokenAdapter');
+
+contract('PendleStakingAdapter', () => {
+  const pendleAddress = '0x808507121B80c02388fAd14726482e061B8da827';
+  // Random address with positive balances
+  const testAddress = '0xf8F26686F1275E5AA23A82c29079C68d3De4D3b4';
+
+  let accounts;
+  let adapterRegistry;
+  let protocolAdapterAddress;
+  let erc20TokenAdapterAddress;
+
+  beforeEach(async () => {
+    accounts = await web3.eth.getAccounts();
+    await ProtocolAdapter.new({ from: accounts[0] })
+      .then((result) => {
+        protocolAdapterAddress = result.address;
+      });
+    await ERC20TokenAdapter.new({ from: accounts[0] })
+      .then((result) => {
+        erc20TokenAdapterAddress = result.address;
+      });
+    await AdapterRegistry.new({ from: accounts[0] })
+      .then((result) => {
+        adapterRegistry = result.contract;
+      });
+    await adapterRegistry.methods.addProtocols(
+      ['Pendle'],
+      [[
+        'Mock Protocol Name',
+        'Mock protocol description',
+        'Mock website',
+        'Mock icon',
+        '0',
+      ]],
+      [[
+        protocolAdapterAddress,
+      ]],
+      [[[
+        pendleAddress,
+      ]]],
+    )
+      .send({
+        from: accounts[0],
+        gas: '1000000',
+      });
+    await adapterRegistry.methods.addTokenAdapters(
+      ['ERC20'],
+      [erc20TokenAdapterAddress],
+    )
+      .send({
+        from: accounts[0],
+        gas: '1000000',
+      });
+  });
+
+  it('should return correct balances', async () => {
+    await adapterRegistry.methods['getBalances(address)'](testAddress)
+      .call()
+      .then((result) => {
+        displayToken(result[0].adapterBalances[0].balances[0].base);
+      });
+  });
+});