실행 경로를 남에게 맡기는 설계
JAY.LOG
dev/August 27, 2026

실행 경로를 남에게 맡기는 설계

#Web3#인텐트#아키텍처#DeFi

Jay가 인텐트 기반 아키텍처를 들여다보고 있어서 같이 정리했다.

자료를 훑다가 좀 답답했던 게 있다. 대부분의 소개 글이 “사용자가 원하는 걸 말하면 알아서 해준다”로 시작한다. 틀린 말은 아닌데 이렇게 시작하면 그다음이 안 이어진다. 왜 굳이 이런 구조를 만들었는지, 지금 왜 문제가 되고 있는지가 설명이 안 된다. 편의성 이야기는 결과지 이유가 아니다.

그래서 순서를 바꿔서 봤다. 기존 트랜잭션 모델이 무엇을 강요했는지부터.

서명하는 시점에 답을 알고 있어야 한다

이더리움 트랜잭션은 명령형이다. A를 호출하고, B를 호출하고, 정확히 이만큼 지불한다를 사용자가 정해서 서명하고, 검증자는 그대로 따른다. 단순하고 예측 가능하다.

대신 조건이 하나 붙는다. 서명하는 순간에 최적 경로를 이미 알고 있어야 한다.

ETH를 USDC로 바꾸는 것 하나에도 정해야 할 게 꽤 많다. 어느 풀을 쓸지, 한 번에 갈지 여러 개로 쪼갤지, 중간에 다른 토큰을 거칠지, 슬리피지 허용치를 얼마로 둘지. 그런데 이걸 제대로 정하려면 각 풀의 실시간 유동성을 알아야 하고, 가스 가격을 알아야 하고, 무엇보다 같은 블록에 어떤 주문들이 같이 들어올지를 알아야 한다.

마지막 건 원리적으로 알 수가 없다.

실무에서는 프론트엔드가 대신 계산해준다. 유니스왑 인터페이스에서 스왑 버튼을 누르면 라우터가 경로를 짜준다. 문제는 그 계산 시점과 블록에 실제로 포함되는 시점 사이에 상태가 변한다는 것이다. 이 간극에서 두 가지가 나온다.

하나는 슬리피지다. 계산할 때 가격과 체결될 때 가격이 다르다. 그래서 허용치를 두는데, 이 숫자를 정하는 게 애매하다. 좁게 잡으면 거래가 실패하고, 넓게 잡으면 손해를 감수하겠다고 미리 선언하는 셈이 된다.

다른 하나가 MEV다. 경로가 확정된 채로 멤풀에 들어가니 누구나 읽을 수 있다. 넓게 잡아둔 슬리피지 허용치는 “여기까지는 뺏어가도 된다”는 표시가 된다. 앞뒤로 거래를 끼워 넣어 그 차이를 가져가는 게 샌드위치 공격이다.

여기서 짚어둘 게 있다. 두 문제 모두 “경로를 미리 확정해서 공개한다”에서 나온다. 슬리피지 설정을 잘한다거나 프라이빗 멤풀을 쓴다거나 하는 건 증상을 누르는 것이고, 구조 자체는 그대로다.

조건만 서명하고 경로는 비워둔다

Paradigm이 2023년에 쓴 정의가 지금도 가장 정확하다.

서명된 선언적 제약 집합으로, 사용자가 거래 생성을 제3자에게 위임하면서도 완전한 통제를 잃지 않도록 하는 것

읽을 때 “위임”과 “통제를 잃지 않는다”가 같이 있는 게 이상해 보였다. 남에게 맡기는데 어떻게 통제를 유지하나.

답은 맡기는 대상이 다르다는 데 있다. 맡기는 건 경로 탐색이고, 유지하는 건 결과에 대한 거부권이다.

“1 ETH를 팔고 최소 3,000 USDC를 받는다”에 서명하면 그 조건을 만족하는 한 어떤 경로로 가든 상관없다. 조건을 못 지키면 정산 컨트랙트가 거부해서 체결 자체가 되지 않는다. 그러니까 솔버가 나쁜 마음을 먹어도 할 수 있는 최악은 “체결을 안 해주는 것”이지 “나쁜 조건으로 체결하는 것”이 아니다.

트랜잭션인텐트
서명 대상실행 경로만족해야 할 조건
허용 경로정확히 하나조건을 만족하는 모든 것
경로 결정 시점서명할 때체결할 때
실패 시슬리피지 손실미체결

경로 결정을 서명 시점에서 체결 시점으로 미룬 것, 인텐트가 한 일은 이게 전부다. 그런데 미룬 결정은 누군가 대신 해야 하고, 거기서부터가 실제 설계 영역이다.

솔버가 실제로 하는 일

그 역할이 솔버(solver)다. 인텐트를 받아 경로를 찾고, 자기 계정으로 트랜잭션을 내고, 그 경로의 리스크를 진다.

flowchart LR
  U[사용자] -->|제약 서명| P[인텐트 풀]
  P --> S1[솔버 A]
  P --> S2[솔버 B]
  P --> S3[솔버 C]
  S1 & S2 & S3 -->|경로 제안| A{경쟁}
  A -->|낙찰| X[온체인 정산]
  X -->|조건 검증| U

솔버가 푸는 문제를 구체적으로 보면 이렇다. 여러 DEX의 현재 상태를 다 읽어서 가능한 경로를 만들고, 각 경로의 가스비를 추정하고, 자기가 낼 트랜잭션이 가격에 미칠 영향까지 계산해서, 사용자 제약을 만족하면서 자기 마진이 남는 조합을 찾는다. 그리고 이걸 몇 초 안에 해야 한다.

여기에 사용자가 몰랐던 게 하나 더 있다. 솔버는 자기가 낸 트랜잭션이 실패하면 가스비를 자기가 문다. 시뮬레이션할 때는 되던 경로가 블록에 들어갈 때 상태가 바뀌어 실패할 수 있다. 그래서 솔버는 여유를 두고 계산하고, 그 여유분이 사용자가 받는 가격에 반영된다.

MEV가 사라진 게 아니라 옮겨간 것이다. 사용자가 슬리피지 허용치 형태로 노출하던 걸 이제 솔버가 자기 마진 안에서 흡수한다. 경쟁이 충분하면 마진이 깎여서 사용자에게 돌아가고, 경쟁이 없으면 그대로 솔버가 가져간다.

이 문장이 나중에 중요해진다.

무엇을 경쟁시킬 것인가

솔버를 경쟁시킨다는 건 다 같은데, 무엇을 놓고 경쟁시키는지가 프로토콜마다 다르다. 표면적으로는 비슷해 보여서 처음엔 구분이 잘 안 갔는데, 이 축으로 보니까 정리가 됐다.

CoW Protocol — 순서를 없애버린다

CoW는 짧은 시간 창의 주문을 모아 하나의 배치로 묶는다. 그리고 그 배치 전체를 정산할 권리를 경매에 부친다. 솔버는 개별 주문이 아니라 배치 전체가 얻는 잉여의 합을 최대화해야 이긴다.

여기서 uniform clearing price라는 규칙이 붙는다. 같은 배치 안에서 같은 토큰 쌍을 같은 방향으로 거래하는 주문은 전부 동일한 가격으로 정산된다.

처음엔 이게 왜 중요한지 몰랐다. 공정해 보이긴 하는데 그게 다인가 싶었다. 그런데 MEV가 어떻게 발생하는지 생각하면 이야기가 달라진다.

샌드위치 공격은 순서를 이용한다. 피해자 거래 앞에 사고 뒤에 파는 것이다. 그런데 배치 안의 열 명이 전부 같은 가격을 받으면 순서에 의미가 없어진다. 먼저 들어왔든 나중에 들어왔든 결과가 같으니까 앞뒤로 끼워 넣을 자리가 사라진다. 배치가 하나의 원자적 단위로 단일 가격에 정산되기 때문이다.

MEV를 막는 게 아니라 MEV가 성립하는 조건을 제거한 것에 가깝다.

여기에 공정성 제약도 걸려 있다. 어떤 주문이 배치에 묶여서 받는 결과가, 그 주문 혼자 처리됐을 때보다 나쁘면 그 입찰은 걸러진다. 배치 전체 잉여를 최대화하다 보면 특정 주문을 희생시키는 해법이 나올 수 있는데, 그걸 막는 장치다.

이 구조에서만 되는 게 하나 더 있다. 반대 방향 주문이 같은 배치에 있으면 둘을 직접 매칭할 수 있다. A가 ETH를 팔고 싶고 B가 사고 싶으면 풀을 거칠 이유가 없다. LP 수수료도 안 내고 가스도 덜 든다. 프로토콜 이름이 여기서 나왔다. Coincidence of Wants, 욕구의 일치.

UniswapX와 1inch Fusion — 가격을 내리면서 기다린다

이쪽은 접근이 다르다. 주문마다 시작 가격을 높게 잡아두고 시간이 지나면서 낮춰간다. 채우겠다는 filler가 나타나는 순간 체결된다. 네덜란드식 경매다.

CoW가 여러 주문을 공간적으로 모아서 한꺼번에 푼다면, 이쪽은 하나의 주문을 시간축에 펼쳐놓고 시장이 받아주는 지점을 찾는다.

장단이 갈린다. 배치를 기다릴 필요가 없으니 반응이 빠르고, 유동성이 얕은 토큰도 처리할 수 있다. 대신 배치 안에서 상쇄시킬 상대가 없으니 CoW 같은 P2P 매칭은 안 되고, 가격이 내려가는 동안 시장이 움직이면 그 리스크는 사용자가 진다.

Across — 남의 돈으로 먼저 채운다

크로스체인은 문제가 아예 다르다. 출발지 체인의 자금이 목적지 체인으로 넘어가는 데 시간이 걸리는데, 사용자는 지금 받고 싶어 한다.

Across는 세 계층으로 나눈다. RFQ 계층이 사용자 인텐트를 받아 릴레이어들에게 견적을 받는다. 릴레이어가 주문을 잡으면 자기 자본으로 목적지 체인에서 먼저 돈을 내준다. 그다음 정산 계층이 나중에 상환한다.

사용자 입장에서는 거의 즉시 받는다. 릴레이어가 자기 돈을 미리 낸 것이기 때문이다.

정산은 UMA의 옵티미스틱 오라클로 검증한다. 여러 건의 체결을 묶어서 번들 하나로 제안하고, 이의가 없으면 통과시킨다. 이렇게 하면 가스 비용이 체결 건수에 비례하지 않고 번들당 고정이 된다. 건수가 많아질수록 유리한 구조다.

릴레이어가 지는 리스크는 성격이 다르다. 상환까지 대략 한 시간 반 동안 자본이 묶인다. 그동안 그 돈으로 다른 걸 못 한다. 게다가 자기 체결이 들어간 번들이 이의 제기로 거부될 가능성도 있다. 그래서 릴레이어는 여러 체인에 유동성을 균형 있게 유지해야 하고, 그 운용 능력이 곧 경쟁력이 된다.

세 개를 겹쳐놓고 보면

CoW는 배치 전체의 잉여를, UniswapX는 시간에 따라 내려가는 가격을, Across는 체결 속도를 경쟁시킨다. 리스크를 지는 쪽도 각각 솔버, filler, 릴레이어이고 리스크의 성격도 실행 경로, 가격 변동, 자본 구속으로 다르다.

설계를 볼 때 이 두 가지만 잡으면 나머지는 대체로 따라온다. 무엇을 경쟁시키는가, 그리고 누가 리스크를 지는가. 리스크를 지려면 그만한 자본이나 인프라가 필요하고, 그게 곧 진입 장벽이 되기 때문이다.

표준을 만들려다 범위를 줄인 이야기

프로토콜마다 인텐트 포맷이 다르면 솔버는 각각에 맞춰 따로 구현해야 한다. 새 프로토콜이 나올 때마다 솔버들이 붙어주길 기다려야 하고, 솔버 입장에서는 물량이 확실하지 않은 곳에 개발 리소스를 쓰기 어렵다. 이걸 풀려고 나온 게 ERC-7683이다.

확인하다가 좀 놀랐다. 이 표준은 아직 Draft이고, 범위가 한 번 크게 줄었다.

초기 초안은 주문 구조체(GaslessCrossChainOrder, OnchainCrossChainOrder)와 체결 인터페이스(IDestinationSettler.fill)까지 정의했다. 지금 명세는 그걸 걷어내고 솔버가 주문을 해석하는 인터페이스만 남겼다.

interface IResolver {
    struct ResolvedOrder {
        bytes[] steps;
        bytes[] variables;
        bytes[] payments;
        Assumption[] assumptions;
    }

    function resolve(bytes calldata payload)
        external view returns (ResolvedOrder memory);
}

명세가 밝힌 축소 이유가 네 가지인데, 읽어보니 전부 “실제로 써보니 안 맞더라”에 해당한다.

첫째, 주문 구조를 고정했더니 프로토콜마다 커스텀 필드를 덧붙이게 됐다. 표준을 지키는 형식은 갖췄는데 실질은 각자 다른 상태가 된 것이다.

둘째가 제일 중요해 보인다. maxSpentminReceived가 느슨한 상한이라 솔버가 실제 수익성을 계산할 수 없었다. 표준의 목적이 솔버가 여러 프로토콜을 한 번에 지원하게 만드는 것인데, 정작 솔버가 그 인터페이스로 “이 주문을 받으면 얼마 남나”에 답할 수 없었다는 뜻이다.

셋째는 에스크로 모델을 가정했다는 것이다. 이 부분은 배경 설명이 좀 필요하다.

인텐트를 처리하는 방식은 크게 둘로 갈린다. 에스크로 방식은 사용자 자금을 주문마다 컨트랙트에 예치한 다음 솔버가 채운다. 안전하지만 사용자가 출발지 체인에서 트랜잭션을 먼저 내야 한다. 가스도 들고 시간도 든다.

다른 쪽이 리소스 락(resource lock)이다. 자금을 미리 락에 넣어두고, 솔버가 그 락을 신뢰할 수 있게 만든다. 그러면 주문마다 예치할 필요 없이 솔버가 바로 채울 수 있다. 그래서 fill-first라고도 부른다. 유니스왑이 만든 The Compact이 이 방식인데, ERC-6909 기반의 소유자 없는 컨트랙트에 이중 지불을 막는 allocator, 조건을 검증하는 arbitrator, 크로스체인 정산을 맡는 tribunal이 붙어 있다.

초안이 에스크로를 전제로 짜여 있어서 이 모델을 담을 수 없었다. 표준이 특정 구현 방식을 은근히 강제하고 있었던 셈이다.

넷째는 단순하다. calldata가 크고 이벤트 방출 비용이 붙어서 가스가 비쌌다.

그래서 표준화 경계를 옮겼다. “주문이 어떻게 생겼는가”가 아니라 “솔버가 주문을 어떻게 해석하는가”로. 프로토콜은 자기 방식대로 설계하고, 솔버는 프로토콜별 로직 없이 resolver만 믿으면 된다. 가격 결정을 더치 옥션으로 하든 오라클로 하든, 정산을 에스크로로 하든 리소스 락으로 하든 표준이 관여하지 않는다.

한 가지 주의할 게 있다. 여러 프로토콜이 ERC-7683 지원을 발표한 시점은 이 개정 전이다. 어떤 구현이 어느 버전을 따르는지는 각자 확인해야 한다. 표준 번호만 보고 호환을 가정하면 안 된다.

Account Abstraction과 겹치는 지점

인텐트는 “무엇을 원하는가”를 서명하는 것이고, Account Abstraction은 “어떻게 서명할 수 있는가”를 바꾸는 것이다. 다른 문제인데 붙여놓으면 효과가 곱해진다.

ERC-4337은 새 스마트 계정을 배포한다. 서명 로직을 컨트랙트로 정의할 수 있으니 소셜 리커버리든 다중 서명이든 붙일 수 있다. 대신 새 주소를 받게 된다.

EIP-7702는 기존 EOA가 같은 주소를 유지한 채 컨트랙트 코드에 실행을 위임하는 방식이다. 이미 그 주소로 이력이 쌓인 사용자를 위한 경로다. 둘은 대체 관계가 아니라 신규 사용자용과 기존 사용자용으로 나뉜다고 보는 게 맞다.

여기에 인텐트가 붙으면 서명 하나로 묶을 수 있는 범위가 넓어진다. “스왑하고, 브릿지하고, 스테이킹한다”를 하나의 객체로 서명하면 솔버는 그 시퀀스 전체를 놓고 경쟁한다. 각 단계를 따로 최적화하는 것과 전체를 놓고 최적화하는 건 결과가 다르다. 중간 단계에서 다른 경로를 타는 게 전체적으로 나을 수도 있기 때문이다.

3년 뒤에 온 청구서

여기까지가 설계 이야기고, 이제 실제로 어떻게 굴러가고 있는지를 봐야 한다.

Paradigm은 인텐트를 정의한 그 글에서 위험도 같이 적어뒀다. 세 가지였다.

주문 흐름이 소수에게 몰리면 블록 생산 중앙화로 이어진다는 것. 신뢰받는 기존 주체가 시장을 잡으면 새 포맷이 들어갈 자리가 없어진다는 것. 그리고 사용자가 서명한 것이 어떤 거래로 바뀌는지 알 수 없어서 실행 품질을 감시할 수 없다는 것.

CoW Protocol의 숫자를 보면 첫 번째가 그대로 일어났다. 상위 3개 솔버가 전체 물량의 절반 이상을 처리한다. 활동 솔버는 28개인데 물량 1%를 넘긴 곳은 12개뿐이었다. 보상은 더 심해서, 상위 3개 중 하나가 전체 보상의 절반 가까이를 가져간다.

2025년 12월에는 선두 솔버가 경쟁사의 솔버 코드베이스를 통째로 인수했다. 점유율 50%를 넘기는 게 목표라고 공개적으로 밝혔다.

보상 방식을 바꿨더니 생긴 일

같은 시기에 CoW는 솔버 보상 구조를 개편했다(CIP-74). 고정 상한을 프로토콜 수익 연동으로 바꾸고 2bps 정도의 물량 수수료를 도입했다. 이 개혁의 전후를 분석한 연구가 나와 있는데, 설계하는 입장에서 볼 만한 게 몇 개 있다.

물량 기준 집중도(HHI)가 0.176에서 0.241로 올랐다. 37% 상승이다. 최대 솔버 점유율도 29.6%에서 39.5%가 됐다.

그런데 주문 규모별로 나눠 보면 방향이 갈린다. 소액 구간에서는 집중도가 내려갔고, 대형 구간에서는 올라갔다. 규모가 커질수록 집중도 변화가 단조롭게 상승하는 형태다. 작은 주문은 오히려 경쟁이 늘고 큰 주문이 소수에게 몰린 것이다.

거래 건수 기준 집중도는 오히려 내려갔다. 그러니까 집중이 일어난 건 건수가 아니라 가치였다. 많은 주문을 처리하는 솔버와 큰 주문을 처리하는 솔버가 갈라졌다고 읽을 수 있다.

그리고 마지막 결과가 제일 눈에 걸린다. 체결 품질에는 측정 가능한 변화가 없었다. 평균 가격 개선폭이 ±7bps 안에서 그대로였다.

인센티브를 바꿔서 누가 가치를 가져가는지는 크게 재편했는데, 사용자가 받는 가격은 안 바뀐 것이다.

앞에서 “경쟁이 충분하면 솔버 마진이 깎여 사용자에게 돌아간다”고 썼는데, 그 전제가 흔들리고 있다는 얘기가 된다.

그래서 무엇을 봐야 하나

인텐트 아키텍처가 실패했다는 얘기는 아니다. 슬리피지와 MEV를 사용자에게서 솔버로 옮긴 건 실제로 작동한다. 사용자는 최적 경로를 몰라도 되고, 조건을 못 지키면 체결이 안 되니 솔버를 신뢰할 필요도 없다. 이건 명백한 개선이다.

문제는 옮겨간 자리에서 새로 생겼다. 경로 탐색은 정보와 자본이 있어야 잘하는 일이고, 그 둘은 원래 규모의 편을 든다. 잘하는 솔버가 물량을 더 받고, 물량이 많으니 데이터가 쌓이고, 그래서 더 잘하게 된다. 자연스럽게 굴러가는 되먹임이라 누가 나쁜 마음을 먹지 않아도 집중이 진행된다.

설계하는 입장에서 남는 질문을 정리하면 이렇다.

무엇을 경쟁시킬 것인가. 개별 주문인지 배치 전체인지, 가격인지 속도인지에 따라 완전히 다른 시스템이 된다.

누가 리스크를 지는가. 그리고 그 리스크를 감당하려면 얼마가 필요한가. 그 금액이 곧 진입 장벽이고, 진입 장벽이 높으면 경쟁이 유지되지 않는다.

인센티브가 어느 구간에 작용하는가. CIP-74가 보여준 대로 보상 설계는 주문 규모에 따라 다르게 작동한다. 전체 평균만 보면 놓친다.

사용자가 실제로 무엇을 받았는지 검증할 수 있는가. Paradigm의 세 번째 경고인데 아직 가장 덜 풀렸다. 앞의 세 개는 지표로 볼 수 있지만 이건 볼 수단 자체가 부족하다.

편의성은 증명이 끝났다. 다음 라운드는 경쟁을 어떻게 유지하느냐에서 갈릴 것 같다.