No se limite a escribir declaraciones require para funciones específicas; escriba declaraciones require para sus protocolos. Las comprobaciones de cumplimiento de funciones (requisitos)-eficacia (Efectos)-interacciones (INteracciones) + invariancia de protocolo (Iniants) o el modo FREI-PI pueden ayudar a que su contrato sea más seguro, porque obliga a los desarrolladores a centrarse en la seguridad a nivel de función. También tenga cuidado para invariantes a nivel de protocolo.
motivación
En marzo de 2023, Euler Finance fue pirateada y perdió 200 millones de dólares. Euler Finance es un mercado de préstamos donde los usuarios pueden depositar garantías y pedir prestado contra ellas. Tiene algunas características únicas, de hecho, es un mercado de préstamos comparable a Compound Finance y Aave.
Puedes leer una autopsia sobre este truco aquí. Su contenido principal es la falta de controles de salud en una función específica, lo que permite a los usuarios romper la invariancia fundamental del mercado de préstamos.
Iniciantes fundamentales
En el núcleo de la mayoría de los protocolos DeFi se encuentra la inmutabilidad, una propiedad del estado del programa que se espera que siempre sea cierta. También es posible tener múltiples invariantes, pero en general, se construyen alrededor de una idea central. Aquí hay unos ejemplos:
Al igual que en el mercado de préstamos: los usuarios no pueden realizar ninguna acción para colocar una cuenta en una posición de garantía insegura o menos segura ("menos segura" significa que ya está por debajo del umbral mínimo de seguridad y, por lo tanto, no se puede retirar más).
En AMM DEX: x * y == k, x + y == k, etc.
En el staking de minería de liquidez: los usuarios solo deberían poder retirar la cantidad de tokens de staking que depositaron.
Lo que salió mal con Euler Finance no fue necesariamente que agregaran funciones, no escribieran pruebas o no siguieran las mejores prácticas tradicionales. Ellos auditaron la actualización y realizaron pruebas, pero aun así se les pasó por alto. El problema central es que se olvidan de una invariante central del mercado crediticio (¡al igual que los auditores!).
*Nota: no estoy tratando de molestar a Euler, son un equipo talentoso, pero este es un caso reciente. *
El núcleo del problema
Probablemente estés pensando: "Bueno, es cierto. Es por eso que fueron pirateados; olvidaron una declaración de requisito". Si y no.
Pero, ¿por qué olvidarían la instrucción require?
verificar - validar - la interacción no es lo suficientemente buena
Un patrón común recomendado para los desarrolladores de solidez es el patrón Comprobaciones-Efectos-Interacciones. Es muy útil para eliminar errores relacionados con la reentrada y, a menudo, aumenta la cantidad de validación de entrada que tiene que hacer un desarrollador. _Pero_, es propenso al problema de no ver el bosque por los árboles.
Lo que le enseña al desarrollador es: "Primero escribo mi declaración requerida, luego hago la validación, luego tal vez hago alguna interacción, luego estoy seguro". El problema es que, la mayoría de las veces, se convierte en una mezcla de controles y efectos, no está mal, ¿eh? Las interacciones aún son definitivas, por lo que el reingreso no es un problema. Pero obliga a los usuarios a centrarse en funciones más específicas y transiciones de estado individuales en lugar del contexto global más amplio. Esto significa que:
El mero patrón de verificación-validación-interacción hace que los desarrolladores se olviden de las invariantes centrales de sus protocolos.
Sigue siendo un patrón excelente para los desarrolladores, pero siempre se debe garantizar la invariancia del protocolo (en serio, ¡debe seguir usando CEI!).
Hazlo bien: modo FREI-PI
Tomemos, por ejemplo, este fragmento del contrato SoloMargin de dYdX (código fuente), que es un mercado de préstamos y un contrato comercial apalancado. Este es un buen ejemplo de lo que llamo el patrón Requisitos de función-Efectos-Interacciones + Iniciadores de protocolo, o el patrón FREI-PI.
Como tal, creo que este es el único mercado de préstamos en el mercado de préstamos en etapa inicial que no tiene vulnerabilidades relacionadas con el mercado. Compound y Aave no tienen problemas directos, pero sus bifurcaciones sí. Y bZx ha sido pirateado muchas veces.
Examine el siguiente código y observe las siguientes abstracciones:
Verifique los parámetros de entrada (_verifyInputs).
Acción (conversión de datos, manipulación de estado)
Verifique el estado final (_verifyFinalState).
Se siguen realizando las Comprobaciones-Efectos-Interacciones habituales. Vale la pena señalar que la interacción de validación de verificación con verificaciones adicionales no es equivalente a FREI-PI: son similares pero tienen objetivos fundamentalmente diferentes. Por lo tanto, los desarrolladores deberían pensar en ellos como diferentes: FREI-PI, como una abstracción superior, apunta a la seguridad del protocolo, mientras que CEI apunta a la seguridad funcional.
La estructura de este contrato es realmente interesante: los usuarios pueden realizar las acciones que deseen (depósito, préstamo, comercio, transferencia, liquidación, etc.) en una cadena de acciones. ¿Quiere depositar 3 fichas diferentes, retirar una cuarta y liquidar una cuenta? Es una sola llamada.
Este es el poder de FREI-PI: los usuarios pueden hacer lo que quieran dentro del protocolo, siempre que las invariantes del mercado principal de préstamos se mantengan al final de la llamada: un solo usuario no puede realizar ninguna acción que haga que una cuenta quede insegura. o más Posiciones colaterales inseguras. Para este contrato, esto se realiza en _verifyFinalState, verificando la garantía de cada cuenta afectada para asegurarse de que el acuerdo es mejor que cuando se inició la transacción.
Hay algunas invariantes adicionales incluidas en esta función que complementan las invariantes centrales y ayudan con funciones secundarias como el cierre de mercados, pero son las verificaciones centrales las que realmente mantienen el protocolo seguro.
FREI-PI centrado en la entidad
Otro problema con FREI-PI es el concepto centrado en la entidad. Tomemos como ejemplo un mercado de préstamos y supuestos invariantes centrales:
Técnicamente, esta no es la única invariante, pero lo es para la entidad del usuario (sigue siendo una invariante del protocolo central y, por lo general, las invariantes del usuario son invariantes del protocolo central). Los mercados de préstamos también suelen tener 2 entidades adicionales:
Oráculo
Gestión / Gobernanza
Cada inmutabilidad adicional hace que el protocolo sea más difícil de garantizar, por lo que cuanto menos, mejor. Esto es en realidad lo que dijo Dan Elitzer en su artículo titulado: Por qué DeFi está roto y cómo solucionarlo #1 Protocolo sin Oracle (pista: el artículo en realidad no dice que los oráculos son el problema).
Oráculo
Para los oráculos, tome el exploit Cream Finance de $ 130 millones. La inmutabilidad central de las entidades del oráculo:
Resulta que verificar oráculos en tiempo de ejecución con FREI-PI es complicado, pero factible, con un poco de previsión. En términos generales, Chainlink es una buena opción para confiar en su mayoría, ya que satisface la mayor parte de la inmutabilidad. En el raro caso de manipulación o sorpresa, puede ser beneficioso tener salvaguardas que reduzcan la flexibilidad a favor de la precisión (como verificar que el último valor conocido sea un porcentaje mayor que el valor actual). Además, el sistema SoloMargin de dYdX hace un gran trabajo con su oráculo DAI, aquí está el código (si no puede saberlo, creo que es el mejor sistema de contrato inteligente complejo jamás escrito).
Para obtener más información sobre la evaluación de Oracle y resaltar las capacidades del equipo de Euler, escribieron un buen artículo sobre la manipulación computacional de los precios de Oracle Uniswap V3 TWAP.
Administración / Gobernanza
La creación de invariantes para entidades administradas es la más complicada. Esto se debe principalmente al hecho de que la mayor parte de su función es cambiar otras invariantes existentes. Dicho esto, si puede evitar el uso de roles administrativos, debería hacerlo.
Fundamentalmente, las invariantes centrales de una entidad administrada podrían ser:
Interpretación: los administradores pueden hacer cosas que deberían terminar sin romper los invariantes, a menos que cambien las cosas drásticamente para proteger los fondos de los usuarios (p. ej., mover activos a un contrato de rescate es eliminar los invariantes). Los administradores también deben ser considerados usuarios, por lo que la invariancia del usuario del mercado principal de préstamos también debería ser válida para ellos (lo que significa que no pueden atacar a otros usuarios o protocolos). Actualmente, algunas acciones del administrador son imposibles de verificar en tiempo de ejecución a través de FREI-PI, pero con invariantes lo suficientemente fuertes en otros lugares, es de esperar que la mayoría de los problemas puedan mitigarse. Digo actualmente, porque uno puede imaginar usar un sistema de prueba zk que podría verificar el estado completo del contrato (por usuario, por oráculo, etc.).
Como ejemplo de un administrador que rompe la inmutabilidad, tome la acción de gobernanza Compound que borró el mercado de cETH en agosto de 2022. Fundamentalmente, esta actualización rompe la inmutabilidad de Oracle: Oracle proporciona información precisa y (relativamente) en tiempo real. Debido a la falta de funcionalidad, Oracle puede proporcionar información incorrecta. Una verificación FREI-PI en tiempo de ejecución, comprobando que el Oracle afectado puede proporcionar información en tiempo real, puede evitar que esto suceda con la actualización. Esto se puede incorporar en _setPriceOracle para verificar si todos los activos recibieron la información en tiempo real. Lo bueno de FREI-PI para los roles de administrador es que los roles de administrador son relativamente insensibles al precio (o al menos deberían serlo), por lo que un mayor uso de gas no debería ser un gran problema.
La complejidad es peligrosa
Entonces, si bien las invariantes más importantes son las invariantes centrales del protocolo, también puede haber algunas invariantes centradas en la entidad que deben ser mantenidas por las invariantes centrales. Sin embargo, el conjunto de invariantes más simple (y más pequeño) es probablemente el más seguro. Simple es bueno Un ejemplo brillante es Uniswap...
Por qué Uniswap nunca ha sido pirateado (probablemente)
Los AMM pueden tener la invariancia básica más simple de cualquier primitiva DeFi: tokenBalanceX * tokenBalanceY == k (por ejemplo, modelo de producto constante). Cada función en Uniswap V2 gira en torno a este simple invariante:
Menta: añadido a k
Quemar: restar de k
Intercambiar: transferir x e y, pero mantener k.
Skim: reajustar tokenBalanceX * tokenBalanceY para que sea igual a k, y eliminar la parte redundante.
El secreto de seguridad de Uniswap V2: el núcleo es una inmutabilidad simple y todas las funciones están al servicio de este. La única otra entidad que se puede argumentar es la gobernanza, que puede activar un cambio de tarifa, que no toca la inmutabilidad central, solo la distribución de la propiedad del saldo del token. Esta simplicidad en su declaración de seguridad es la razón por la cual Uniswap nunca ha sido pirateado. La simplicidad no es en realidad un desprecio por los excelentes desarrolladores de los contratos inteligentes de Uniswap, por el contrario, se necesitan excelentes ingenieros para encontrar la simplicidad.
Problema de gasolina
Mi Twitter ya está lleno de gritos optimizacionistas de horror y dolor de que estos controles son innecesarios e ineficientes. Dos cosas sobre esta pregunta:
¿Sabes qué más es ineficiente? Tuve que enviar mensajes a ~~Laurence~~ piratas informáticos norcoreanos a través de etherscan, transferir dinero usando ETH y amenazar con que el FBI intervendría.
Probablemente ya cargó todos los datos que necesita del almacenamiento, por lo que al final de la llamada, solo agregue un poco de verificación requerida a los datos activos. ¿Quiere que su acuerdo cueste una tarifa insignificante o dejarlo morir?
Si el costo es prohibitivo, reconsidere las variables centrales e intente simplificar.
¿Qué significa esto para mi?
Como desarrollador, es importante definir y expresar las invariantes centrales al principio del proceso de desarrollo. Como sugerencia concreta: la primera función para escribirse es _verifyAfter, para verificar sus invariantes después de cada llamada a su contrato. Póngalo en su contrato y despliéguelo allí. Complemente este invariante (y otros invariantes centrados en entidades) con pruebas de invariantes más amplias que se verifican antes de la implementación (guía de Foundry).
Las tiendas transitorias abren algunas optimizaciones y mejoras interesantes con las que Nascent experimentará. Le sugiero que considere cómo se pueden usar las tiendas transitorias como una herramienta para una mayor seguridad en los contextos de llamadas.
En este artículo, no se dedica mucho tiempo a la introducción del modelo FREI-PI para la validación de entradas, pero también es muy importante. Definir los límites de la entrada es una tarea desafiante para evitar el desbordamiento y situaciones similares. Considere verificar y seguir el progreso de nuestra herramienta: pirómetro (actualmente en versión beta, por favor dénos una estrella). Puede profundizar y ayudar a encontrar lugares donde quizás no esté realizando la validación de entrada.
en conclusión
Además de cualquier acrónimo pegadizo (FREI-PI) o nombre de esquema, lo realmente importante es:
Encuentre la simplicidad en la inmutabilidad central de su protocolo. Y trabaja como el demonio para asegurarte de que nunca se destruya (o se atrape antes de que lo haga).
Ver originales
This page may contain third-party content, which is provided for information purposes only (not representations/warranties) and should not be considered as an endorsement of its views by Gate, nor as financial or professional advice. See Disclaimer for details.
Un nuevo modelo de seguridad de contratos DeFi: enfoque en la invariancia del protocolo
Resumen
No se limite a escribir declaraciones require para funciones específicas; escriba declaraciones require para sus protocolos. Las comprobaciones de cumplimiento de funciones (requisitos)-eficacia (Efectos)-interacciones (INteracciones) + invariancia de protocolo (Iniants) o el modo FREI-PI pueden ayudar a que su contrato sea más seguro, porque obliga a los desarrolladores a centrarse en la seguridad a nivel de función. También tenga cuidado para invariantes a nivel de protocolo.
motivación
En marzo de 2023, Euler Finance fue pirateada y perdió 200 millones de dólares. Euler Finance es un mercado de préstamos donde los usuarios pueden depositar garantías y pedir prestado contra ellas. Tiene algunas características únicas, de hecho, es un mercado de préstamos comparable a Compound Finance y Aave.
Puedes leer una autopsia sobre este truco aquí. Su contenido principal es la falta de controles de salud en una función específica, lo que permite a los usuarios romper la invariancia fundamental del mercado de préstamos.
Iniciantes fundamentales
En el núcleo de la mayoría de los protocolos DeFi se encuentra la inmutabilidad, una propiedad del estado del programa que se espera que siempre sea cierta. También es posible tener múltiples invariantes, pero en general, se construyen alrededor de una idea central. Aquí hay unos ejemplos:
Lo que salió mal con Euler Finance no fue necesariamente que agregaran funciones, no escribieran pruebas o no siguieran las mejores prácticas tradicionales. Ellos auditaron la actualización y realizaron pruebas, pero aun así se les pasó por alto. El problema central es que se olvidan de una invariante central del mercado crediticio (¡al igual que los auditores!).
*Nota: no estoy tratando de molestar a Euler, son un equipo talentoso, pero este es un caso reciente. *
El núcleo del problema
Probablemente estés pensando: "Bueno, es cierto. Es por eso que fueron pirateados; olvidaron una declaración de requisito". Si y no.
Pero, ¿por qué olvidarían la instrucción require?
verificar - validar - la interacción no es lo suficientemente buena
Un patrón común recomendado para los desarrolladores de solidez es el patrón Comprobaciones-Efectos-Interacciones. Es muy útil para eliminar errores relacionados con la reentrada y, a menudo, aumenta la cantidad de validación de entrada que tiene que hacer un desarrollador. _Pero_, es propenso al problema de no ver el bosque por los árboles.
Lo que le enseña al desarrollador es: "Primero escribo mi declaración requerida, luego hago la validación, luego tal vez hago alguna interacción, luego estoy seguro". El problema es que, la mayoría de las veces, se convierte en una mezcla de controles y efectos, no está mal, ¿eh? Las interacciones aún son definitivas, por lo que el reingreso no es un problema. Pero obliga a los usuarios a centrarse en funciones más específicas y transiciones de estado individuales en lugar del contexto global más amplio. Esto significa que:
El mero patrón de verificación-validación-interacción hace que los desarrolladores se olviden de las invariantes centrales de sus protocolos.
Sigue siendo un patrón excelente para los desarrolladores, pero siempre se debe garantizar la invariancia del protocolo (en serio, ¡debe seguir usando CEI!).
Hazlo bien: modo FREI-PI
Tomemos, por ejemplo, este fragmento del contrato SoloMargin de dYdX (código fuente), que es un mercado de préstamos y un contrato comercial apalancado. Este es un buen ejemplo de lo que llamo el patrón Requisitos de función-Efectos-Interacciones + Iniciadores de protocolo, o el patrón FREI-PI.
Como tal, creo que este es el único mercado de préstamos en el mercado de préstamos en etapa inicial que no tiene vulnerabilidades relacionadas con el mercado. Compound y Aave no tienen problemas directos, pero sus bifurcaciones sí. Y bZx ha sido pirateado muchas veces.
Examine el siguiente código y observe las siguientes abstracciones:
Se siguen realizando las Comprobaciones-Efectos-Interacciones habituales. Vale la pena señalar que la interacción de validación de verificación con verificaciones adicionales no es equivalente a FREI-PI: son similares pero tienen objetivos fundamentalmente diferentes. Por lo tanto, los desarrolladores deberían pensar en ellos como diferentes: FREI-PI, como una abstracción superior, apunta a la seguridad del protocolo, mientras que CEI apunta a la seguridad funcional.
La estructura de este contrato es realmente interesante: los usuarios pueden realizar las acciones que deseen (depósito, préstamo, comercio, transferencia, liquidación, etc.) en una cadena de acciones. ¿Quiere depositar 3 fichas diferentes, retirar una cuarta y liquidar una cuenta? Es una sola llamada.
Este es el poder de FREI-PI: los usuarios pueden hacer lo que quieran dentro del protocolo, siempre que las invariantes del mercado principal de préstamos se mantengan al final de la llamada: un solo usuario no puede realizar ninguna acción que haga que una cuenta quede insegura. o más Posiciones colaterales inseguras. Para este contrato, esto se realiza en _verifyFinalState, verificando la garantía de cada cuenta afectada para asegurarse de que el acuerdo es mejor que cuando se inició la transacción.
Hay algunas invariantes adicionales incluidas en esta función que complementan las invariantes centrales y ayudan con funciones secundarias como el cierre de mercados, pero son las verificaciones centrales las que realmente mantienen el protocolo seguro.
FREI-PI centrado en la entidad
Otro problema con FREI-PI es el concepto centrado en la entidad. Tomemos como ejemplo un mercado de préstamos y supuestos invariantes centrales:
Técnicamente, esta no es la única invariante, pero lo es para la entidad del usuario (sigue siendo una invariante del protocolo central y, por lo general, las invariantes del usuario son invariantes del protocolo central). Los mercados de préstamos también suelen tener 2 entidades adicionales:
Cada inmutabilidad adicional hace que el protocolo sea más difícil de garantizar, por lo que cuanto menos, mejor. Esto es en realidad lo que dijo Dan Elitzer en su artículo titulado: Por qué DeFi está roto y cómo solucionarlo #1 Protocolo sin Oracle (pista: el artículo en realidad no dice que los oráculos son el problema).
Oráculo
Para los oráculos, tome el exploit Cream Finance de $ 130 millones. La inmutabilidad central de las entidades del oráculo:
Resulta que verificar oráculos en tiempo de ejecución con FREI-PI es complicado, pero factible, con un poco de previsión. En términos generales, Chainlink es una buena opción para confiar en su mayoría, ya que satisface la mayor parte de la inmutabilidad. En el raro caso de manipulación o sorpresa, puede ser beneficioso tener salvaguardas que reduzcan la flexibilidad a favor de la precisión (como verificar que el último valor conocido sea un porcentaje mayor que el valor actual). Además, el sistema SoloMargin de dYdX hace un gran trabajo con su oráculo DAI, aquí está el código (si no puede saberlo, creo que es el mejor sistema de contrato inteligente complejo jamás escrito).
Para obtener más información sobre la evaluación de Oracle y resaltar las capacidades del equipo de Euler, escribieron un buen artículo sobre la manipulación computacional de los precios de Oracle Uniswap V3 TWAP.
Administración / Gobernanza
La creación de invariantes para entidades administradas es la más complicada. Esto se debe principalmente al hecho de que la mayor parte de su función es cambiar otras invariantes existentes. Dicho esto, si puede evitar el uso de roles administrativos, debería hacerlo.
Fundamentalmente, las invariantes centrales de una entidad administrada podrían ser:
Interpretación: los administradores pueden hacer cosas que deberían terminar sin romper los invariantes, a menos que cambien las cosas drásticamente para proteger los fondos de los usuarios (p. ej., mover activos a un contrato de rescate es eliminar los invariantes). Los administradores también deben ser considerados usuarios, por lo que la invariancia del usuario del mercado principal de préstamos también debería ser válida para ellos (lo que significa que no pueden atacar a otros usuarios o protocolos). Actualmente, algunas acciones del administrador son imposibles de verificar en tiempo de ejecución a través de FREI-PI, pero con invariantes lo suficientemente fuertes en otros lugares, es de esperar que la mayoría de los problemas puedan mitigarse. Digo actualmente, porque uno puede imaginar usar un sistema de prueba zk que podría verificar el estado completo del contrato (por usuario, por oráculo, etc.).
Como ejemplo de un administrador que rompe la inmutabilidad, tome la acción de gobernanza Compound que borró el mercado de cETH en agosto de 2022. Fundamentalmente, esta actualización rompe la inmutabilidad de Oracle: Oracle proporciona información precisa y (relativamente) en tiempo real. Debido a la falta de funcionalidad, Oracle puede proporcionar información incorrecta. Una verificación FREI-PI en tiempo de ejecución, comprobando que el Oracle afectado puede proporcionar información en tiempo real, puede evitar que esto suceda con la actualización. Esto se puede incorporar en _setPriceOracle para verificar si todos los activos recibieron la información en tiempo real. Lo bueno de FREI-PI para los roles de administrador es que los roles de administrador son relativamente insensibles al precio (o al menos deberían serlo), por lo que un mayor uso de gas no debería ser un gran problema.
La complejidad es peligrosa
Entonces, si bien las invariantes más importantes son las invariantes centrales del protocolo, también puede haber algunas invariantes centradas en la entidad que deben ser mantenidas por las invariantes centrales. Sin embargo, el conjunto de invariantes más simple (y más pequeño) es probablemente el más seguro. Simple es bueno Un ejemplo brillante es Uniswap...
Por qué Uniswap nunca ha sido pirateado (probablemente)
Los AMM pueden tener la invariancia básica más simple de cualquier primitiva DeFi: tokenBalanceX * tokenBalanceY == k (por ejemplo, modelo de producto constante). Cada función en Uniswap V2 gira en torno a este simple invariante:
El secreto de seguridad de Uniswap V2: el núcleo es una inmutabilidad simple y todas las funciones están al servicio de este. La única otra entidad que se puede argumentar es la gobernanza, que puede activar un cambio de tarifa, que no toca la inmutabilidad central, solo la distribución de la propiedad del saldo del token. Esta simplicidad en su declaración de seguridad es la razón por la cual Uniswap nunca ha sido pirateado. La simplicidad no es en realidad un desprecio por los excelentes desarrolladores de los contratos inteligentes de Uniswap, por el contrario, se necesitan excelentes ingenieros para encontrar la simplicidad.
Problema de gasolina
Mi Twitter ya está lleno de gritos optimizacionistas de horror y dolor de que estos controles son innecesarios e ineficientes. Dos cosas sobre esta pregunta:
Si el costo es prohibitivo, reconsidere las variables centrales e intente simplificar.
¿Qué significa esto para mi?
Como desarrollador, es importante definir y expresar las invariantes centrales al principio del proceso de desarrollo. Como sugerencia concreta: la primera función para escribirse es _verifyAfter, para verificar sus invariantes después de cada llamada a su contrato. Póngalo en su contrato y despliéguelo allí. Complemente este invariante (y otros invariantes centrados en entidades) con pruebas de invariantes más amplias que se verifican antes de la implementación (guía de Foundry).
Las tiendas transitorias abren algunas optimizaciones y mejoras interesantes con las que Nascent experimentará. Le sugiero que considere cómo se pueden usar las tiendas transitorias como una herramienta para una mayor seguridad en los contextos de llamadas.
En este artículo, no se dedica mucho tiempo a la introducción del modelo FREI-PI para la validación de entradas, pero también es muy importante. Definir los límites de la entrada es una tarea desafiante para evitar el desbordamiento y situaciones similares. Considere verificar y seguir el progreso de nuestra herramienta: pirómetro (actualmente en versión beta, por favor dénos una estrella). Puede profundizar y ayudar a encontrar lugares donde quizás no esté realizando la validación de entrada.
en conclusión
Además de cualquier acrónimo pegadizo (FREI-PI) o nombre de esquema, lo realmente importante es:
Encuentre la simplicidad en la inmutabilidad central de su protocolo. Y trabaja como el demonio para asegurarte de que nunca se destruya (o se atrape antes de que lo haga).