Skip to content
This repository was archived by the owner on Dec 10, 2025. It is now read-only.
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 69 additions & 59 deletions contracts/token/LendToAaveMigrator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,74 +5,84 @@ import {IERC20} from "../interfaces/IERC20.sol";
import {SafeMath} from "../open-zeppelin/SafeMath.sol";
import {VersionedInitializable} from "../utils/VersionedInitializable.sol";


/**
* @title LendToAaveMigrator
* @notice This contract implements the migration from LEND to AAVE token
* @author Aave
*/
* @title LendToAaveMigrator
* @notice Implements the migration from LEND to AAVE
* @dev Proxy-initialized via VersionedInitializable
*/
contract LendToAaveMigrator is VersionedInitializable {
using SafeMath for uint256;
using SafeMath for uint256;

IERC20 public immutable AAVE;
IERC20 public immutable LEND;
uint256 public immutable LEND_AAVE_RATIO;
uint256 public constant REVISION = 1;

uint256 public _totalLendMigrated;

/**
* @dev Emitted on every migration call
* @param sender Caller performing the migration
* @param amount Amount of LEND migrated (in LEND units)
* @param aaveOut Amount of AAVE sent (in AAVE units)
*/
event LendMigrated(address indexed sender, uint256 indexed amount, uint256 indexed aaveOut);

IERC20 public immutable AAVE;
IERC20 public immutable LEND;
uint256 public immutable LEND_AAVE_RATIO;
uint256 public constant REVISION = 1;

uint256 public _totalLendMigrated;
/**
* @param aave The AAVE token address
* @param lend The LEND token address
* @param lendAaveRatio The exchange rate LEND:AAVE (e.g. 100 means 100 LEND -> 1 AAVE)
*/
constructor(IERC20 aave, IERC20 lend, uint256 lendAaveRatio) public {
require(address(aave) != address(0), "AAVE_ZERO");
require(address(lend) != address(0), "LEND_ZERO");
require(lendAaveRatio > 0, "RATIO_ZERO");
AAVE = aave;
LEND = lend;
LEND_AAVE_RATIO = lendAaveRatio;
}

/**
* @dev emitted on migration
* @param sender the caller of the migration
* @param amount the amount being migrated
*/
event LendMigrated(address indexed sender, uint256 indexed amount);
/**
* @dev Initializes the implementation (proxy pattern)
*/
function initialize() public initializer {}

/**
* @param aave the address of the AAVE token
* @param lend the address of the LEND token
* @param lendAaveRatio the exchange rate between LEND and AAVE
*/
constructor(IERC20 aave, IERC20 lend, uint256 lendAaveRatio) public {
AAVE = aave;
LEND = lend;
LEND_AAVE_RATIO = lendAaveRatio;
}
/**
* @dev Returns true if migration has started (contract initialized via proxy)
*/
function migrationStarted() external view returns (bool) {
return lastInitializedRevision != 0;
}

/**
* @dev initializes the implementation
*/
function initialize() public initializer {
}
/**
* @dev Executes migration from LEND to AAVE
* Caller must approve this contract to spend their LEND beforehand
* @param amount Amount of LEND to migrate
*/
function migrateFromLEND(uint256 amount) external {
require(lastInitializedRevision != 0, "MIGRATION_NOT_STARTED");
require(amount > 0, "ZERO_AMOUNT");

/**
* @dev returns true if the migration started
*/
function migrationStarted() external view returns(bool) {
return lastInitializedRevision != 0;
}
// Pull LEND from user
require(LEND.transferFrom(msg.sender, address(this), amount), "LEND_PULL_FAIL");

// Calculate AAVE out (integer division truncates dust by design)
uint256 aaveOut = amount.div(LEND_AAVE_RATIO);
require(aaveOut > 0, "INSUFFICIENT_FOR_1_AAVE");

/**
* @dev executes the migration from LEND to AAVE. Users need to give allowance to this contract to transfer LEND before executing
* this transaction.
* @param amount the amount of LEND to be migrated
*/
function migrateFromLEND(uint256 amount) external {
require(lastInitializedRevision != 0, "MIGRATION_NOT_STARTED");
// Send AAVE to user
require(AAVE.transfer(msg.sender, aaveOut), "AAVE_SEND_FAIL");

_totalLendMigrated = _totalLendMigrated.add(amount);
LEND.transferFrom(msg.sender, address(this), amount);
AAVE.transfer(msg.sender, amount.div(LEND_AAVE_RATIO));
emit LendMigrated(msg.sender, amount);
}
// Bookkeeping
_totalLendMigrated = _totalLendMigrated.add(amount);

/**
* @dev returns the implementation revision
* @return the implementation revision
*/
function getRevision() internal pure override returns (uint256) {
return REVISION;
}
emit LendMigrated(msg.sender, amount, aaveOut);
}

}
/**
* @dev Implementation revision
*/
function getRevision() internal pure override returns (uint256) {
return REVISION;
}
}