개발 가이드
이 장에서는 플래시론을 활용하여 개발하는 방법 및 동작 방식을 알아보기위해 가장 간단한 형태의 예시와 함께 설명합니다. 아래의 가이드에서 설명의 편의를 위해 플래시론을 활용해 개발할 컨트랙트를 A컨트랙트라 표기하도록 하겠습니다.
A컨트랙트는 클레이 뱅크의 LendingPool 컨트랙트와 상호작용하게 됩니다. 플래시론을 통한 코드의 진행순서는 다음과 같습니다.
1. 플래시론을 활용할 상황이 생겼을 때 개발자가 컨트랙트의 특정 함수를 호출합니다. 여기서는 예시로 exampleFlashLoanCall
을 호출했다고 가정합니다. 즉 A컨트랙트에는 exampleFlashLoanCall
함수가 구현되어 있습니다.
2. exampleFlashLoanCall
함수에서 필요한 자산 과 양을 설정하여 LendingPool 컨트랙트 에 FlashLoan을 요청하는 flashLoan
함수를 호출합니다. 파라미터에 대한 설명은 여기를 참고해주세요.
3. LendingPool 컨트랙트는 A컨트랙트가 요청한 금액만큼 자산을 전달합니다.
4. LendingPool 컨트랙트는 A컨트랙트의 executeOperation
함수를 호출합니다. executeOperation
는 IFlashLoanReceiver
에 정의되어있으며 플래시론을 활용할 컨트랙트는 이 인터페이스를 반드시 구현해야합니다. 각 파라미터에대한 설명은 여기를 참고해주세요.
즉 A컨트랙트가 실제로 자산을 빌려 동작을 수행하는 코드는 executeOperation
함수 내에서 수행되게 됩니다. executeOperation
함수는 내부에서 자산을 활용한 뒤 반드시 상환해야할 양(amounts
+ premium
) 만큼의 자산(토큰) 을 보유하고 있어야 합니다. 또한 LendingPool 컨트랙트가 회수해 갈 수 있도록 상환해야할 양 이상 토큰을 LendingPool 컨트랙트에 approve 해주어야 합니다.
5. LendingPool 컨트랙트 는 마지막으로 amounts
+ premium
만큼의 토큰을 A컨트랙트 로부터 회수(transferFrom) 해옵니다.
위의 1~5 까지의 동작중에 예외가 발생하거나 특히
4. 에서 A컨트랙트 가 false를 리턴하는경우
5. 에서 LendingPool 컨트랙트가 자산이 회수가 불가능한 경우
모든 실행이 취소됩니다.
따라서 대출자(Borrower)는 담보 없이 자산을 빌릴 수 있고, 대여자(Depositor)는 위험성 없이 수수료를 얻을 수 있습니다.
지금까지의 과정을 도식으로 보면 아래와 같습니다.
파라미터 설명(flashLoan)
아래는 flashLoan
함수를 호출하기위한 파라미터와 이에대한 설명입니다.
address receiverAddress
: 플래시론을 통해 대출을 발생시켰을 때 자산을 받아가고,executeOperation
가 구현되어있는 주소입니다. 이 예제에서는 A컨트랙트가receiverAddress
가 됩니다.address[] calldata assets
: 대출 받을 자산의 목록입니다.uint256[] calldata amounts
: 대출 받을 자산의 양 목록입니다.uint256[] calldata modes
: 대출 받을 자산들에 대해 대출 모드를 설정합니다. 현재 클레이뱅크의 대출모드는 0만 지원하며 나머지 타입은 추후 지원 예정입니다. 모드는 다음과 같습니다.0 : 즉시 상환을 의미합니다. 플래시론을 통해 빌린 자산은 트랜잭션 종료와 함께 반드시 상환되어야 합니다. 그렇지 않은경우 실패합니다.
address onBehalfOf
: 대출모드가 0이아닐때 사용됩니다. 현재는 값이 무시되므로msg.sender
를 입력하셔도 무방합니다.bytes calldata params
: LendingPool 컨트랙트가executeOperation
을 통해 사용자 A컨트랙트를 호출할때 넘겨줄 파라미터를 지정할 수 있습니다.uint16 referralCode
: 특정상황에 레퍼럴 구분자로 이용하기 위한 파라미터입니다. 일반 사용시에는 0을 입력하면 됩니다.
파라미터 설명(IFlashLoanReceiver)
아래는 executeOperation
함수를 호출하기위한 파라미터와 이에대한 설명입니다.
address[] calldata assets
: 대출한 자산 목록을 의미합니다.uint256[] calldata amounts
: 대출한 금액 목록을 의미합니다.uint256[] calldata premiums
: 대출한 자산에 대한 수수료가 반영된 금액 목록을 의미합니다. 즉amount
+premium
만큼을 상환해야합니다.address initiator
: 플래시론을 호출한 주소를 나타냅니다.bytes calldata params
: 플래시론을 호출할때 넘겨준 파라미터 데이터를 나타냅니다
예시 컨트랙트
아래는 지금까지 설명했던 A컨트랙트의 예시입니다.
더 알아보기
플래시론을 활용할때 클레이뱅크 LedingPool 컨트랙트 의 flashLoan
함수를 호출하고 executeOperation
를 구현하는 것들이 모두 하나의 컨트랙트 (예시에서는 A컨트랙트) 일 필요는 없습니다.
필요에 따라서 일반 계정(EOA)에서 flashLoan
를 호출하고 receiverAddress
에 executeOperation
를 구현한 컨트랙트 주소(예시에서는 A컨트랙트)를 기입해도 무방합니다. 또한 또다른 컨트랙트인 B컨트랙트에서 호출할수도 있습니다. 각각 모두 msg.sender
가 달라짐을 유의합니다.
위와같이 누구나 flashLoan
을 호출하여 다른 컨트렉트의 executeOperation
을 호출할 수 있으므로 griefing공격을 조심해야합니다. 해당 공격은 다음과 같이 이루어질 수 있습니다.
A컨트랙트에 자산(토큰)을 가지고있고 플래시론을 위해
executeOperation()
이 구현되어있는경우B컨트랙트가
flashloan()
에receiverAddress
파라미터로 A컨트랙트 주소를 넣고 실행할 수 있습니다.이 경우 A컨트랙트의
executeOperation()
가 실행 될 것이고, 클레이뱅크의 LendingPool은 A컨트랙트로부터 자산 회수를 시도합니다.A컨트랙트에 자산이 있기때문에 자산회수가 성공하게되고 A컨트랙트 코드에 따라 자산손실이 발생할 수 있습니다.
이 공격을 막기위해서 executeOperation
함수에 적절한 방어로직(initiator 화이트리스팅, 자산 전,후 비교 require문 등..)을 충분히 고려하는것을 권장합니다.
활용방안
클레이 뱅크의 플래시론을 활용하여 순간 큰 자산이 필요할 때 기능을 수행할 수 있습니다.
클레이튼 내 DEX내에서의 큰 규모의 차액거래(Arbitrage) 기회가 생겼을때 활용하여 차액을 획득할 수 있으며
클레이뱅크 뿐만아니라 다른 대출 프로토콜들의 청산기회가 생겼을때 없는 자산을 빌려 청산을 진행하고 청산 보너스를 얻을 수 있습니다.
이 외 한 트랜잭션내에 큰 규모의 자산을 빌려 이득을 취할수 상황이 있다면 플래시론을 활용하여 큰 이익을 얻을 수 있습니다.
Last updated